numpy(三)
NumPy广播机制
NumPy 中的广播机制(Broadcast)旨在解决不同形状数组之间的算术运算问题。我们知道,如果进行运算的两个数组形状完全相同,它们直接可以做相应的运算
1 | import numpy as np |
但如果两个形状不同的数组呢?它们之间就不能做算术运算了吗?当然不是!为了保持数组形状相同,NumPy 设计了一种广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。
当进行运算的两个数组形状不同,Numpy 会自动触发广播机制
1 | import numpy as np |
NumPy遍历数组
NumPy 提供了一个 nditer 迭代器对象,它可以配合 for 循环完成对数组元素的遍历。
使用 arange() 函数创建一个 3*4 数组,并使用 nditer 生成迭代器对象。
1 | import numpy as np |
遍历顺序
在内存中,Numpy 数组提供了两种存储数据的方式,分别是 C-order(行优先顺序)与 Fortrant-order(列优先顺序)。nditer 迭代器选择了一种与数组内存布局一致的顺序,之所以这样做,是为了提升数据的访问效率。
在默认情况下,当我们遍历数组中元素的时候,不需要考虑数组的存储顺序,这一点可以通过遍历上述数组的转置数组来验证。
1 | import numpy as np |
从示例的输出结果可以看出,a 和 a.T 的遍历顺序是一样的,也就是说,它们在内存中的存储顺序是一样的。
下面以 C 样式访问转置数组的副本
1 | import numpy as np |
通过示例可知 a.T.copy(order = ‘C’) 的遍历结果与前面的数组遍历结果不一样。究其原因,就是因为它们在内存中的存储方式不一样。
指定遍历顺序
您可以通过 nditer 对象的order参数来指定数组的遍历的顺序。
1 | import numpy as np |
修改数组元素值
nditer 对象提供了一个可选参数op_flags,它表示能否在遍历数组时对元素进行修改。它提供了三种模式
- read-only
只读模式,在这种模式下,遍历时不能修改数组中的元素。
read-write
读写模式,遍历时可以修改元素值。write-only
只写模式,在遍历时可以修改元素值。1
2
3
4
5
6
7import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print ("原数组是:",a)
for x in np.nditer(a, op_flags=['readwrite']):
x[...]=2*x
print ('修改后的数组是:',a)
外部循环使用
nditer 对象的构造函数有一个“flags”参数,它可以接受以下参数值:
c_index
可以跟踪 C 顺序的索引。
f_index
可以跟踪 Fortran 顺序的索引。
multi_index
每次迭代都会跟踪一种索引类型。
external_loop
返回的遍历结果是具有多个值的一维数组。
1 | import numpy as np |
迭代多个数组
如果两个数组都能够被广播,那么 nditer 对象就可以同时对它们迭代。
假设数组 a 的维度是 34,另一个数组 b 的维度是 14 (即维度较小的数组 b 可以被广播到数组 a 中)
1 | import numpy as np |
NumPy相关数组操作
NumPy 中包含了一些处理数组的常用方法,大致可分为以下几类:
数组变维操作
数组转置操作
修改数组维度操作
连接与分割数组操作
数组变维操作
reshape
在不改变数组元素的条件下,修改数组的形状。
flat
返回是一个迭代器,可以用 for 循环遍历其中的每一个元素。
flatten
以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。
ravel
返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。
numpy.ndarray.flat
numpy.ndarray.flat 返回一个数组迭代器1
2
3
4
5
6
7import numpy as np
a = np.arange(9).reshape(3,3)
for row in a:
print (row)
#使用flat属性:
for ele in a.flat:
print (ele,end=",")numpy.ndarray.flatten()
numpy.ndarray.flatten 返回一份数组副本,对副本修改不会影响原始数组
语法格式:ndarray.flatten(order=’C’)
1 | import numpy as np |
- numpy.ravel()
numpy.ravel() 将多维数组中的元素以一维数组的形式展开,该方法返回数组的视图(view),如果修改,则会影响原始数组。
numpy.ravel(a, order=’C’)
1 | import numpy as np |
数组转置操作
transpose
将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。
ndarray.T
与 transpose 方法相同。
rollaxis
沿着指定的轴向后滚动至规定的位置。
swapaxes
对数组的轴进行对换。
- numpy.transpose()
numpy.transpose() 用于对换多维数组的维度,比如二维数组使用此方法可以实现矩阵转置
语法格式:numpy.transpose(arr, axes)
arr:要操作的数组
axes:可选参数,元组或者整数列表,将会按照该参数进行转置
1 | import numpy as np |
- numpy.rollaxis()
该方法表示沿着指定的轴,向后滚动至一个特定位置
格式如下:numpy.rollaxis(arr, axis, start)
arr:要传入的数组;
axis:沿着哪条轴向后滚动,其它轴的相对位置不会改变;
start:默认以 0 轴开始,可以根据数组维度调整它的值。
- numpy.swapaxes()
该方法用于交换数组的两个轴,
语法格式:numpy.swapaxes(arr, axis1, axis2)
1 | import numpy as np |
修改数组维度操作
修改数组维度的操作,主要有以下方法:
broadcast
生成一个模拟广播的对象。
broadcast_to
将数组广播为新的形状。
expand_dims
扩展数组的形状。
squeeze
从数组的形状中删除一维项。
- numpy.broadcast()
返回值是数组被广播后的对象,该函数以两个数组作为输入参数
1 | import numpy as np |
- numpy.broadcast_to()
该函数将数组广播到新形状中,它在原始数组的基础上返回一个只读视图。 如果新形状不符合 NumPy 的广播规则,则会抛出 ValueError 异常。函数的语法格式如下:numpy.broadcast_to(array, shape, subok)
1 | import numpy as np |
- numpy.expand_dims()
在指定位置插入新的轴,从而扩展数组的维度,语法格式如下:numpy.expand_dims(arr, axis)
参数说明:arr:输入数组axis:新轴插入的位置
1 | import numpy as np |
- numpy.squeeze()
删除数组中维度为 1 的项,例如,一个数组的 shape 是 (5,1),经此函数后,shape 变为 (5,) 。其函数语法格式如下:
numpy.squeeze(arr, axis)
参数说明:arr:输入数的组;axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项。
下面是带有 axis 参数的实例:
1 | >>> x = np.array([[[0], [1], [2]]]) |
1 | import numpy as np |
连接与分割数组操作
连接与分割数组是数组的两种操作方式
1) 连接数组操作 numpy.concatenate()
沿指定轴连接相同形状的两个或多个数组
格式如下:numpy.concatenate((a1, a2, …), axis)
a1, a2, …:表示一系列相同类型的数组;
axis:沿着该参数指定的轴连接数组,默认为 0。
创建两个 a 、b 数组,并沿指定轴将它们连接起来。注意两个数组的形状要保持一致。
1 | import numpy as np |
数组连接操作至少需要两个维度相同的数组,才允许对它们进行垂直或者水平方向上的操作。在垂直方向堆叠数组
1 | import numpy as np |
2) 分割数组操作
numpy.split() 沿指定的轴将数组分割为多个子数组
语法格式:numpy.split(ary, indices_or_sections, axis)
ary:被分割的数组
indices_or_sections:若是一个整数,代表用该整数平均切分,若是一个数组,则代表沿轴切分的位置(左开右闭);
axis:默认为0,表示横向切分;为1时表示纵向切分。
1 | import numpy as np |
最后看一下 hsplit() 的使用方法
1 | import numpy as np |