读书笔记五--numpy
数组转置和轴对换
转置是重塑的一种特殊形式,返回的是源数据的视图(不会进行任何复制操作)。数组不仅有transpose方法,还有一个特殊的T属性:
arr=np.arange(15).reshape((3,5)) arr Out[56]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]) arr.T Out[57]: array([[ 0, 5, 10], [ 1, 6, 11], [ 2, 7, 12], [ 3, 8, 13], [ 4, 9, 14]])
进行矩阵计算时,经常需要用到该操作,比如利用np.dot计算矩阵内积:
arr=np.random.randn(6,3) np.dot(arr.T,arr) Out[59]: array([[2.39679519, 0.23607287, 0.27316386], [0.23607287, 5.3207093 , 0.6367557 ], [0.27316386, 0.6367557 , 3.50480009]])
对于高维数组,transpose需要得到一个由轴编号组成的元组才能对这些轴进行转置:
arr=np.arange(16).reshape((2,2,4)) arr Out[61]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.transpose((1,0,2)) Out[62]: array([[[ 0, 1, 2, 3], [ 8, 9, 10, 11]], [[ 4, 5, 6, 7], [12, 13, 14, 15]]])
还有一个swapaxes方法,它需要接收一对轴编号:
arr Out[63]: array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]], [[ 8, 9, 10, 11], [12, 13, 14, 15]]]) arr.swapaxes(1,2) Out[64]: array([[[ 0, 4], [ 1, 5], [ 2, 6], [ 3, 7]], [[ 8, 12], [ 9, 13], [10, 14], [11, 15]]])
swapaxes也是返回源数据的视图(不会进行任何复制操作)。
通用函数:快速的元素级数组函数
通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。可以将其看做简单函数(接收一个或多个标量值,并产生一个或多个标量值)的矢量化包装器。
许多ufunc都是简单的元素级变体,如sqrt和exp:
x=np.random.randn(8) x Out[7]: array([-0.45367765, 0.45448697, 0.05901557, -1.14350864, 0.93985719, -1.37405764, 0.54604076, -1.52919879]) y=np.random.randn(8) y Out[9]: array([-2.44401238, -0.57907323, -2.42303926, 0.25004382, 0.78757902, 0.13324314, 0.8643189 , 0.6892275 ]) #x,y中的每个元素进行对比,选较大的值 np.maximum(x,y) Out[10]: array([-0.45367765, 0.45448697, 0.05901557, 0.25004382, 0.93985719, 0.13324314, 0.8643189 , 0.6892275 ])
有些ufunc可以返回多个数组,modf就是一个例子,它是Python内置函数divmod的矢量化版本,用于浮点数组的小数和整数部分。
1 arr=np.random.randn(7)*5 2 3 arr 4 Out[12]: 5 array([ 1.36965276, -0.29453957, 5.0043914 , -3.93568688, -4.50608498, 6 1.40926456, -1.99294205]) 7 8 #modf返回的2个数组分别是浮点数的小数部分和整数部分 9 np.modf(arr) 10 Out[13]: 11 (array([ 0.36965276, -0.29453957, 0.0043914 , -0.93568688, -0.50608498, 12 0.40926456, -0.99294205]), array([ 1., -0., 5., -3., -4., 1., -1.]))
一元ufunc(几个常用的)
abs、fabs | 计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs |
sqrt | 计算各元素的平方根,相当于arr**0.5 |
square | 计算各元素的平方,相当于arr**2 |
exp | 计算各元素的指数 |
二元ufunc
add | 将数组中对应的元素相加 |
substract | 从第一个数组中减去第二个数组中的元素 |
multiply | 数组元素相乘 |
divide、floor_divide | 除法或向下圆整除法(丢弃余数) |
利用数组进行数据处理
用数组表达式代替循环的做法,通常被称为矢量化。一般来说,矢量化数组运算要比等价的纯Python方式快上一两个数量级(甚至更多),尤其是各种数值计算。
假设我们想要在一组值(网格型)上计算函数sqrt(x**2+y**2)。np.meshgrid函数接受两个一维数组,并产生两个二维矩阵:
1 points=np.arange(-5,5,0.01) 2 3 xs,ys=np.meshgrid(points,points) 4 5 ys 6 Out[16]: 7 array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ], 8 [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99], 9 [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98], 10 ..., 11 [ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97], 12 [ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98], 13 [ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])
现在把这两个数组当做两个浮点数那样编写表达式:
1 import matplotlib.pyplot as plt 2 3 z=np.sqrt(xs**2+ys**2) 4 5 z 6 Out[21]: 7 array([[7.07106781, 7.06400028, 7.05693985, ..., 7.04988652, 7.05693985, 8 7.06400028], 9 [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815, 10 7.05692568], 11 [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354, 12 7.04985815], 13 ..., 14 [7.04988652, 7.04279774, 7.03571603, ..., 7.0286414 , 7.03571603, 15 7.04279774], 16 [7.05693985, 7.04985815, 7.04278354, ..., 7.03571603, 7.04278354, 17 7.04985815], 18 [7.06400028, 7.05692568, 7.04985815, ..., 7.04279774, 7.04985815, 19 7.05692568]]) 20 plt.imshow(z,cmap=plt.cm.gray);plt.colorbar() 21 Out[22]: <matplotlib.colorbar.Colorbar at 0xc95aef0>