使用python进行数据分析<四>(Numpy基础:
Numpy: 一个高性能科学运算和数据分析的基础包. 部分基础功能如下:
Numpy的ndarray :一个多维数组对象
ndarray,一个具有矢量算数运算和复杂广播能力的多维数组. 其中的元素必须是同一个类型. 每个ndarray 都有一个shape记录各维度带下的元组, 一个dtyepe,记录元素类型
创建ndarray对象
nu.array
dat1 = [5,6,57,56,7,657,56,7]
array1 = np.array(dat1)
-
使用np.zeros()创建一个所有元素为0的ndarray
使用np.ones()创建一个所有元素为1的ndarray
使用np.empty()创建一个没有任何具体值的ndarray
image.png
-
array1.astype(np.float64) 转化array中的数据类型.
-
ndarray可以和标量进行数据运算. 如array1 * array1 1/array1. 会将运算作用于每一个元素
-
ndarray支持切片和下标. 不同的是 切片并不会复制出一个新的数组,而是会反映到原数组上. 如果要复制,可以显式的调用copy() ,如: arr[2:4].copy()
-
对多维数组的切片,同理. 逐渐深入. array[1:3,:3]
-
布尔型索引 : 表达式为 array[ array < 0 ] = 1; ndarra 独有的运算方法. python中的list并不具备. 在中括号的表达式中,使用结果为bool的表达式.
-
花式索引 Numpy的一个名词. 对于一个二维的ndarray来说, array[ x ] = 1. 如果x为一个索引. array中的第x个数组中的每个元素赋值为1. 如果x为一个list. 如[1,2,3]. 以list中的每个元素作为下标从array中取出对应的数组, 数组中的每个元素赋值. 如果不进行赋值,就会选取出特定的数组.
-
花式索引传入多个list, list用,分割那么,首先array使用第一个list,截取出对应的数组, 然后使用第二个list,以第二个list中元素作为索引,取出相对应数组中的元素.
array4 = np.arange(32).reshape((8,4))
In [71]: array4
Out[71]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23],
[24, 25, 26, 27],
[28, 29, 30, 31]])
In [75]: array4[[3,4],[1,2]]
Out[75]: array([13, 18])
In [84]: array4[:1,[3,2,1,0]] # :1,代表切片. [3,2,1,0]代表根据idnex取对应的值
Out[84]: array([[3, 2, 1, 0]])
总结: ndarray[] ,可以传入切片,list. index. 根据传入的顺序, 第一个参数用作选取对应的数组. 如果第一个参数是list,第二个参数也是list.那么参照上面第8条. 如果第一个是index或者切片,那么会对每一个数组执行取值排序.
所以说只有两个参数都为list的时候,才会根据返回一个数组. 其他都是对每一个数组做操作
- ndarray的索引,总是把数据复制到一个新的数组中.
- 二维数组可以看做是矩阵. np.dot() 用来计算矩阵的乘法.
数组转置和轴对换
这个有点不好理解. 看了这篇回答才略微明白一点.
In [131]: array7 = np.arange(16).reshape((2,2,4))
In [132]: array7
Out[132]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
In [136]: array8=array7.transpose((1,0,2))
In [137]: array8
Out[137]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
- 创建一个三维数组array7. 此时array7有一个属性x的置默认为 (0,1,2).
- array7调用transpose函数,并传入参数(1,0,2), 也就是 0和1的位置调换.
- 比如在array7中,4的位置为 array7[0][1][0],那么在transpose后的新的数组中, 4的位置要是array[1][0][0]. 就是第一个索引值和第二个索引值的位置互换.
- .T属性返回的值,就是把顺序全部调换的结果. 比如把(0,1,2)变为(2,1,0) . 所以arrray7.T和array7.transpose((2,1,0))的结果是一样的
- swapaxes,就收两个参数,把两个索引上的元素互换 . 所以arrat7.swapaxes(1,2) 和 array7.transpose((0.2.1))的结果是一样的
通用函数
利用数组进行数据处理
Numpy数组将循环简化为数组表达式, 称为矢量化
import numpy as np
import matplotlib.pyplot as plt
points = np.arange(-5,5,0.01)
# np.meshgrid函数接受两个以为数组,并且产生两个二维矩阵,对应两个数组中所有的(x,y)对
xs,ys = np.meshgrid(points,points)
z = np.sqrt(xs**2 + ys**2)
plt.imshow(z,cmap=plt.cm.gray);
plt.colorbar()
plt.show()
将条件逻辑表述为数据表达式 where
where(b,x,y) == b?x:y
In [171]: xarr = np.array([1.1,1.2,1.3,1.4])
In [173]: yarr = np.array([2.1,2.2,2.3,2.4])
In [174]: cond = np.array([True,False,True,False])
In [175]: results = np.where(cond,xarr,yarr)
In [176]: results
Out[176]: array([1.1, 2.2, 1.3, 2.4])
数学和统计学方法
image.png这些函数既可以使用array调用,也可以当做Numpy的顶级函数使用. 函数可以接受一个(axis = )的参数,用于计算该轴向上的统计结果.
cumsum和sumprod不聚合,产生一个等大的数组.
其他聚合,产生一个降一维度的数据
集合逻辑
image.png将数据以二进制格式保存在磁盘
#保存
In [177]: arr = np.arange(10)
In [178]: arr
Out[178]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
In [180]: np.save('one_array',arr)
#读取
In [182]: read_arr = np.load('one_array.npy')
In [183]: read_arr
Out[183]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
#保存多个数组并压缩到一个文件
In [184]: arr1 = np.arange(5)
In [186]: np.savez('z_array',a=arr,b=arr1)
#读取多个数组
In [187]: new_arr = np.load('z_array.npz')
In [188]: new_arr
Out[188]: <numpy.lib.npyio.NpzFile at 0x10fc54eb8>
In [189]: new_arr['a']
Out[189]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
注意单个数组格式为.npy,多个数组压缩的格式为.npz
线性代数相关
image.png这些函数,有的是np下的顶级函数, 有的是linalg下的函数
from numpy.linalg import inv,qr
随机数生成
numpy.random模块对python内置的random进行补充,增加一些用于生成多种概率分布的样本值的函数.
In [204]: samples = np.random.normal(size=(4,4))
In [206]: samples
Out[206]:
array([[ 0.46229648, -0.20647171, -0.00566354, 0.32823414],
[-0.45247886, 0.50668721, -1.20578395, -0.19447529],
[ 0.27184016, 0.74032391, -0.75409531, 1.25058692],
[ 0.35639571, -0.45157067, 0.24709158, 2.4726017 ]])
image.png
使用numpy批量生成随机数
In [207]: nsteps = 1000
#生成1000个随机数
In [208]: draws = np.random.randint(0,2,size=nsteps)
#根据随机数生成 1 或者 -1 的stpes ndarray
In [210]: stpes = np.where(draws > 0,1,-1)
#如果想要一性生成多个,只需要size参数传入一个元组
In [215]: draws = np.random.randint(0,2,size=(5000,1000))
In [216]: steps = np.where(draws > 0,1,-1)
In [217]: steps
Out[217]:
array([[-1, -1, 1, ..., 1, 1, -1],
[-1, -1, -1, ..., 1, -1, -1],
[ 1, 1, 1, ..., 1, 1, -1],
...,
[ 1, -1, 1, ..., 1, -1, 1],
[ 1, -1, -1, ..., -1, 1, -1],
[ 1, 1, 1, ..., -1, -1, -1]])
In [218]: steps.cumsum(1)
Out[218]:
array([[ -1, -2, -1, ..., 28, 29, 28],
[ -1, -2, -3, ..., 0, -1, -2],
[ 1, 2, 3, ..., -50, -49, -50],
...,
[ 1, 0, 1, ..., -24, -25, -24],
[ 1, 0, -1, ..., 52, 53, 52],
[ 1, 2, 3, ..., 16, 15, 14]])