Python3 NumPy基础:数组和矢量计算

目录

 

NumPy介绍:

部分功能如下:

ndarray:

创建ndarray:

ndarray的数据类类型:

数组和标量之间的运算:

数组之间的运算:

数组和标量之间的运算:

基本的索引和切片:

布尔型索引:

花式索引:

数组转置和轴对换:

通用函数:快速的元素级数组函数:

一元函数:

二元函数:

利用数组进行数据处理:

将条件逻辑表述为数组运算:

数学和统计方法:

用于布尔型数组的方法:

排序:

ndarray的基本集合运算:

用于数组的文件输入输出:

线性代数:

伪随机数生成:


NumPy介绍:

NumPy是高性能科学计算和数据分析的基础包。

部分功能如下:

  • ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组
  • 用于对整组数据进行快速运算的标准数学函数(无需编写循环)
  • 用于读写磁盘数据的工具以及用于操作内存映射文件的工具
  • 线性代数、随机数生成以及傅里叶变换功能
  • 用于继承C、C++、Fortran等语言编写的代码的工具

ndarray:

ndarray是一种多维数组对象,它的所有元素必须是相同类型的,每个数组都有一个shape(表示各维度大小的元组)和一个的dtype(表示数组数据类型的对象)

创建ndarray:

函数 说明
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)

ndarray的数据类类型:

类型 类型代码 说明
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)
<ipython-input-34-b0a6caf26928> in <module>
----> 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 计算各个元素的指数e^{x}
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,计算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]: <matplotlib.colorbar.Colorbar at 0x7f7b70466eb8>

 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返回的是数组的已排序副本。

ndarray的基本集合运算:

方法 说明
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)中均匀分布的样本值

 

posted @ 2019-09-18 09:33  Wuliwawa  阅读(468)  评论(0编辑  收藏  举报