目录
NumPy介绍:
部分功能如下:
ndarray:
创建ndarray:
ndarray的数据类类型:
数组和标量之间的运算:
数组之间的运算:
数组和标量之间的运算:
基本的索引和切片:
布尔型索引:
花式索引:
数组转置和轴对换:
通用函数:快速的元素级数组函数:
一元函数:
二元函数:
利用数组进行数据处理:
将条件逻辑表述为数组运算:
数学和统计方法:
用于布尔型数组的方法:
排序:
ndarray的基本集合运算:
用于数组的文件输入输出:
线性代数:
伪随机数生成:
NumPy是高性能科学计算和数据分析的基础包。
ndarray是一种多维数组对象,它的所有元素必须是相同类型的,每个数组都有一个shape(表示各维度大小的元组)和一个的dtype(表示数组数据类型的对象)
函数 | 说明 |
---|---|
array | 将输入数据(列表、元组、数组或其他序列类型)转换为ndarray,可传dtype参数指定数据类型,不传dtype参数numpy会自动推断数据类型。默认直接复制输入数据。 |
asarray | 将输入转换成ndarray,如果输入本身就是ndarray就不进行复制 |
arange | 类似于range,但返回的是一个ndarray不是生成器 |
ones、ones_like | ones根据指定形状(一个用来定义维度的元组)和dtype创建一个全1数组,ones_like以另一个ndarray数组为参数,并根据形状和dtype创建一个全1数组 |
zeros、zeros_like | 类似于ones和ones_like,只不过返回的是全0数组 |
empty、empty_like | 类似于ones和ones_like,之分配空间不填充任何数值(随机数字) |
eye、identity | 创建一个正方的N×N单位矩阵(对角线为1,其余全为0) |
类型 | 类型代码 | 说明 |
---|---|---|
int8、uint8 | i1、u1 | 有符号和无符号的8位(1字节)整型 |
int16、uint16 | i2、u2 | 有符号和无符号的16位(2字节)整型 |
int32、uint32 | i4、u4 | 有符号和无符号的32位(4字节)整型 |
int64、uint64 | i8、u8 | 有符号和无符号的64位(8字节)整型 |
float16 | f2 | 半精度浮点数 |
float32 | f4或f | 标准的单精度浮点数,与C的float兼容 |
float64 | f8或d | 标准的双精度浮点数,与C的double和Python的float兼容 |
float128 | f16或g | 扩展精度浮点数 |
complex64、complex128、complex256 | c8、c16、c32 | 分别用32位、64位和128位浮点数表示的复数 |
bool | ? | 存储True和False的布尔类型 |
object | O | Python对象类型 |
string_ | S | 固定长度的字符串类型(每个字符一个字节)。例如,创建一个长度为10的字符串应使用S10。 |
unicode_ | U | 固定长度的unicode类型(字节数由平台决定)。和字符串定义方式一样(如U10) |
使用ndarray的astype方法可以转换ndarray的数据类型。
In [28]: a1=array([1, 2, 3])
In [30]: a1.astype('S1')
Out[30]: array([b'1', b'2', b'3'], dtype='|S1')
大小相等的数组之间的任何算术运算都会应用到元素级。
In [35]: a1=np.arange(6).reshape((2,3))
In [38]: a1*a1
Out[38]:
array([[ 0, 1, 4],
[ 9, 16, 25]])
In [39]: a1+a1
Out[39]:
array([[ 0, 2, 4],
[ 6, 8, 10]])
大小相同的数组之间的比较会生成布尔值数组:
In [57]: arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])
In [58]: arr2
Out[58]:
array([[ 0., 4., 1.],
[ 7., 2., 12.]])
In [59]: arr2 > arr
Out[59]:
array([[False, True, False],
[ True, False, True]], dtype=bool)
数组与标量的运算会把标量值广播到数组的每个元素。
In [40]: a1 / 1
Out[40]:
array([[0., 1., 2.],
[3., 4., 5.]])
In [41]: a1*2
Out[41]:
array([[ 0, 2, 4],
[ 6, 8, 10]])
数组和标量的比较运算会生成一个与原数组相同维度的布尔型数组。
In [52]: a=np.arange(9).reshape(3,3)
In [53]: a
Out[53]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [54]: a>=5
Out[54]:
array([[False, False, False],
[False, False, True],
[ True, True, True]])
ndarray数组在某一个维度上的切片和普通list对象切片方法相同。([:],[0],[1:],[::2])
数组的切片是原数组的视图不是复制出一个新数组。使用标量对数组的视图赋值时会广播到整个选区。需要真正意义上的复制一个数组应使用copy()方法。
以下两种方式相同:
In [74]: a1[0][2]
Out[74]: 3
In [75]: a1[0, 2]
Out[75]: 3
使用一个数组和一个标量进行比较运算会得到一个布尔型数组,这个布尔型数组可以用于数组索引。
In [60]: index=np.array(['a','b','c','d'])
In [62]: data=np.arange(24).reshape(4,6)
In [63]: data
Out[63]:
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]])
布尔型数组的长度必须跟被索引的轴长度一致。此外,还可以将布尔型数组跟切片、整数混合使用,可以通过~对条件进行否定,需要组合应用多个布尔条件,使用&(和)、|(或)之类的布尔算术运算符。
In [65]: data[(index=='a') | (index!='d')]
Out[65]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
通过布尔型索引选取数组中的数据,将总是创建数据的副本,即使返回一模一样的数组也是如此。
但是对通过布尔型索引选取数组中的数据赋值,将广播到整个索引选中的选区。
In [67]: data[index=='b']=1
In [68]: data
Out[68]:
array([[ 0, 1, 2, 3, 4, 5],
[ 1, 1, 1, 1, 1, 1],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
花式索引(Fancy indexing)是一个NumPy术语,它指的是利用整数数组进行索引。
用一个数组作为索引,选取一个ndarray对象相应维度上指定顺序的列表或ndarray对象,使用负数索引将会从末尾开始选取。
In [2]: a=np.arange(20).reshape(4,5)
In [3]: a
Out[3]:
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
In [4]: a[[0,2]]
Out[4]:
array([[ 0, 1, 2, 3, 4],
[10, 11, 12, 13, 14]])
用小于等于ndarray对象维度个数的整数数组做索引,所有维度对应的索引数组中长度大于1的索引数组长度必须相等。
In [29]: b=np.arange(27).reshape(3,3,3)
In [30]: b
Out[30]:
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]]])
In [31]: b[[0,1,2],[1,1,2],[1]]
Out[31]: array([ 4, 13, 25])
In [32]: b[[2],[1],[1,0,2]]
Out[32]: array([22, 21, 23])
如果索引数组长度大于1的索引数组长度不相等,则会报出索引错误。
In [34]: b[[2,1,0],[2,2]]
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
in
----> 1 b[[2,1,0],[2,2]]
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,)
b[[0,1,2],[1,1,2],[1]]选取的是(0,1,1),(1,1,1,),(2,2,1),并不是像我们想的那样是一个矩形区域。
可以使用下面这种方法选取一个矩形区域。
In [48]: b
Out[48]:
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]]])
In [49]: b[[2,1,0]][:,[1]]
Out[49]:
array([[[21, 22, 23]],
[[12, 13, 14]],
[[ 3, 4, 5]]])
花式索引会把索引选取的数据复制到新数组中。
转置是重塑的一种特殊形式,它返回的是源数据的视图(不会进行任何复制操作)。数组不仅有transpose方法,还有一个特殊的T属性。
ndarray数组的T属性会返回shape是原数组的shape的倒序ndarray对象。
In [95]: d
Out[95]:
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]]])
In [96]: d.shape
Out[96]: (3, 2, 4)
In [97]: d.T
Out[97]:
array([[[ 0, 8, 16],
[ 4, 12, 20]],
[[ 1, 9, 17],
[ 5, 13, 21]],
[[ 2, 10, 18],
[ 6, 14, 22]],
[[ 3, 11, 19],
[ 7, 15, 23]]])
In [98]: d.T.shape
Out[98]: (4, 2, 3)
ndarray数组的transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置。下面这个示例就是把0轴和1轴交换了,2轴没有改变。
In [102]: d
Out[102]:
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]]])
In [103]: d.transpose(1,0,2)
Out[103]:
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11],
[16, 17, 18, 19]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15],
[20, 21, 22, 23]]])
ndarray还有一个swapaxes方法,它需要接受一对轴编号。
In [104]: d
Out[104]:
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]]])
In [105]: d.swapaxes(0,2)
Out[105]:
array([[[ 0, 8, 16],
[ 4, 12, 20]],
[[ 1, 9, 17],
[ 5, 13, 21]],
[[ 2, 10, 18],
[ 6, 14, 22]],
[[ 3, 11, 19],
[ 7, 15, 23]]])
函数 | 说明 |
---|---|
abs,fabs | 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs |
sqrt | 计算各个元素的平方根。相当于arr**0.5 |
square | 计算各个元素的平方。相当于arr**2 |
exp | 计算各个元素的指数 |
log、log10、log2、log1p | 分别为自然对数(底数为e)、底数为10的log、底数为2的log、log(1+x) |
sign | 计算各个元素的正负号:1(整数)、0(零)、-1(负数) |
ceil | 计算各个元素的ceiling值,即大于等于该值的最小整数,向上取整 |
floor | 计算各个元素的floor值,即小于等于该值的最大整数,向下取整 |
rint | 将各个元素值四舍五入到最近的整数,保留dtype |
modf | 将数组的小数和整数部分以两个独立数组的形式返回 |
isnan | 返回一个表示“那些值是NaN(不是数字)”的布尔型数组 |
isfinite、isinf | 分别返回一个表示“表示哪些元素是有穷的”或“哪些元素是无穷的(inf)”的布尔型数组 |
cos、cosh、sin、sinh、tan、tanh | 普通型和双曲型三角函数 |
arccos、arccosh、arcsin、arcsinh、arctan、arctanh | 反三角函数 |
logical_not | 计算各个元素not x的真值,相当于-arr |
函数 | 说明 |
---|---|
add | 将数组中对应的元素相加 |
subtract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法或向下圆整除法(丢弃余数) |
power | 对第一个数组中的元素A,根据第二个数组中的相应元素B,计算 |
maximum、fmax | 元素级的最大值计算。fmax将忽略NaN |
minimum、fmin | 元素级的最小值计算。fmin将忽略NaN |
mod | 元素级的求模计算(除法的余数) |
copysign | 将第二个数组的元素符号赋给第一个数组的值 |
greater、greater_equal、less、less_equal、equal、not_equal | 执行元素级的比较运算,最终产生布尔型数组。相当于中缀运算符>、>=、<、<=、==、!= |
logical_and、logical_or、logical_xor | 执行元素级的针织逻辑运算。相当于中缀运算符&、|、^ |
这些函数可以接受一个out可选参数,可以让数组原地进行操作。需要注意的是out必须是已经存在的ndarray对象并且与返回结果的维度和dtype都相同。
In [181]: d
Out[181]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
In [182]: d1
Out[182]:
array([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1]])
In [183]: np.add(d,d1,d1)
Out[183]:
array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12]])
In [184]: d1
Out[184]:
array([[ 1, 2, 3, 4, 5, 6],
[ 7, 8, 9, 10, 11, 12]])
In [212]: points=np.arange(-5,5,0.01)
In [213]: xs,ys=np.meshgrid(points,points)
In [214]: z=np.sqrt(xs**2+ys**2)
In [215]: from matplotlib import pyplot as plt
In [216]: plt.imshow(z,cmap=plt.cm.gray);plt.colorbar()
Out[216]:
np.meshgrid函数接受两个一维数组,并产生两个二维矩阵(对应于两个数组中所有的(x,y)对),使用matplotlib 的imshow函数创建出下图。
In [165]: xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])
In [166]: yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
In [167]: cond = np.array([True, False, True, True, False])
假设我们想要根据cond中的值选取xarr和yarr的值:当cond中的值为True时,选取xarr的值,否则从yarr中选取。
In [170]: result = np.where(cond, xarr, yarr)
In [171]: result
Out[171]: array([ 1.1, 2.2, 1.3, 1.4, 2.5])
再举一个例子,如果有两个布尔型数组cond1和cond2,希望根据4中不同布尔值组合实现不同的赋值操作。
cond1 | cond2 | result |
---|---|---|
True | True | 0 |
True | False | 1 |
False | True | 2 |
False | False | 3 |
可以这种方式实现
In [217]: np.where(cond1 & cond2,0,np.where(cond1,1,np.where(cond2,2,3)))
或者
In [219]: result=1*(cond1&-cond2)+2*(cond2&-cond1)+3*-(cond1|cond2)
基本数组统计方法
方法 | 说明 |
---|---|
sum | 对数组中全部或某轴向的元素求和。零长度的数组的sum为0 |
mean | 算术平均数。零长度的数组的mean为NaN |
std、var | 分别为标准差和方差,自由度可调(默认为n) |
min、max | 最大值和最小值 |
argmax、argmin | 分别为最大和最小元素的索引 |
cumsum | 所有元素的累计和 |
cumprod | 所有元素的累计积 |
方法 | 说明 |
---|---|
any | 检查数组中是否存在一个或多个True |
all | 检查数组中是否全是True |
ndarray对象的sort是原地排序,多维数组可以在任何一个轴向上进行排序,只需将轴编号传给sort即可,np.sort返回的是数组的已排序副本。
方法 | 说明 |
---|---|
unique(x) | 计算x中的唯一元素,并返回有序结果 |
intersect1d(x,y) | 计算x和y中的公共元素,并返回有序结果 |
union1d(x,y) | 计算x和y的并集,并返回有序结果 |
in1d(x,y) | 得到一个表示“x的元素是否包含于y”的布尔型数组 |
setdiff1d(x,y) | 集合的差,即元素在x中且不在y中 |
setxor1d(x,y) | 集合的对称差,即存在于一个数组中但不同时存在于两个数组中的元素 |
方法 | 说明 |
---|---|
save(path,ndarray) | 将数组ndarray以原始二进制格式保存在路径为path的文件里,文件扩展名为.npy |
load(path) | 从路径为path的.npy文件中读取ndarray数组或者从路径为path的.npz文件中读取一个类似字典的对象,该对象将对各个数组延迟加载 |
savez(path,a=array1,b=array2,...) | 将多个数组保存到一个未压缩文件中,需要将多个数组以关键字参数形式传入 |
savez_compressed(path,a=array1,b=array2,...) | 与savez类似,但是这个方法会把数据压缩后保存到文件中 |
NumPy提供了一个用于矩阵乘法的dot函数,即是ndarray对象的方法又是Numpy命名空间里的一个函数。两个ndarray对象可以使用中缀运算符@进行矩阵乘法运算。
In [3]: a
Out[3]:
array([[0, 1, 2],
[3, 4, 5]])
In [4]: a @ a.T
Out[4]:
array([[ 5, 14],
[14, 50]])
常用的numpy.linalg函数
方法 | 说明 |
---|---|
diag | 以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0) |
dot | 矩阵乘法 |
trace | 计算对角线元素的和 |
det | 计算矩阵行列式 |
eig | 计算方阵的本征值和本征向量 |
inv | 计算方阵的逆 |
prinv | 计算矩阵的Moore-Penrose伪逆 |
qr | 计算QR分解 |
svd | 计算奇异值分解(SVD) |
solve | 解线性方程Ax=b,其中A为一个方阵 |
lstsq | 计算Ax=b的最小二乘解 |
部分numpy.random函数
方法 | 说明 |
---|---|
seed | 确定随机数生成器的种子 |
permutation | 返回一个序列的随机排列或返回一个随机排列的范围 |
shuffle | 对一个序列就地随机排列 |
rand | 产生均匀分布的样本值 |
randint | 从给定的上下限范围内随机选取整数 |
randn | 产生正态分布(平均值为0,标准差为1)的样本值,类似于MATLAB接口 |
binomial | 产生二项分布的样本值 |
normal | 产生正态(高斯)分布的样本值 |
beta | 产生Beta分布的样本值 |
chisquare | 产生卡方分布的样本值 |
gamma | 产生Gamma分布的样本值 |
uniform | 产生在[0,1)中均匀分布的样本值 |