遍历数组
Numpy提供了一个**nditer**
迭代器对象,它可以配合for
循环完成对数组元素的遍历。
import numpy as np
a = np.arange(0, 60, 5).reshape(3, 4)
# 使用nditer迭代器,并使用for进行遍历
for x in np.nditer(a):
print(x, end="\t") # 0 5 10 15 20 25 30 35 40 45 50 55
遍历顺序
在内存中,Numpy数组提供了两种存储方式,分别是C
(行优先)和F
(列优先)。**nditer**
迭代器选择了一种与数组内存布局一致的顺序来处理具有特定存储顺序的数组,之所以这样做,是为了提升数据的访问效率。
- 在默认情况下,当我们遍历数组中元素的时候,不需要考虑数组的存储顺序;
**a**
和**a.T**
(**a**
的转置)的遍历顺序是一样的,意味着它们在内存中的存储顺序是一样的。指定遍历顺序
可通过nditer
对象的**order**
参数来指定数组的遍历顺序。 ```python import numpy as np
a = np.arange(0,60,5) a = a.reshape(3,4) print(a) for x in np.nditer(a, order = ‘C’): print (x,end=”,”) # 0,5,10,15,20,25,30,35,40,45,50,55, for x in np.nditer(a, order = ‘F’): print (x,end=”,”) # 0,20,40,5,25,45,10,30,50,15,35,55,
<a name="kJXhv"></a>
## 修改数组元素值
`nditer` 对象提供了一个可选参数`op_flags`,它**表示能否在遍历数组时对元素进行修改**。
<a name="UtZ8a"></a>
### `read-only`
只读模式,不可修改数组元素值。
<a name="IS2Rm"></a>
### `read-write`
读写模式,可以修改数组元素值。
<a name="HuRXM"></a>
### `write-only`
只写模式,可以修改数组元素值。
```python
import numpy as np
a = np.arange(0,60,5).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 | 返回的遍历结果是具有多个值的一维数组。 |
import numpy as np
a = np.arange(0,60,5)
a = a.reshape(3,4)
print("原数组",a)
#修改后数组
for x in np.nditer(a, flags = ['external_loop'], order = 'F'):
print(x)
迭代多个数组
如果两个数组都能被广播,那么**nditer**
对象就可以同时对它们迭代。
import numpy as np
a = np.arange(0, 60, 5).reshape(3, 4)
print(a)
b = np.array([1, 2, 3, 4], dtype=int)
print(b)
# 广播迭代
for x, y in np.nditer([a, b]):
print("%d:%d" % (x, y), end=",")
相关数组操作
数组变维操作
函数名称 | 函数介绍 |
---|---|
reshape | 在不改变数组元素的条件下,修改数组的形状。 |
flat | 返回的是一个迭代器,可以用 for 循环遍历其中的每一个元素。 |
flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组。 |
ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组)。 |
reshape
flat
(遍历每一个元素)
import 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=",")
flatten
(创建副本后操作)
# 语法格式
ndarray.flatten(order='C')
import numpy as np
a = np.arange(8).reshape(2,4)
print (a)
#默认按行C风格展开的数组
print (a.flatten())
#以F风格顺序展开的数组
print (a.flatten(order = 'F'))
ravel
(返回视图后操作(将修改原始数据))
# 语法格式
numpy.ravel(a, order='C')
import numpy as np
a = np.arange(8).reshape(2,4)
print ('原数组:')
print (a)
print ('调用 ravel 函数后:')
print (a.ravel())
print ('F 风格顺序调用 ravel 函数之后:')
print (a.ravel(order = 'F'))
数组转置操作
函数名称 | 说明 |
---|---|
transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2)。 |
ndarray.T | 与 transpose 方法相同。 |
rollaxis | 沿着指定的轴向后滚动至规定的位置。 |
swapaxes | 对数组的轴进行对换。 |
transpose
numpy.transpose(arr, axes)
其中:
* arr:要操作的数组;
* axes:可选参数,元组或整数列表,将会按该参数进行转置
import numpy as np
a = np.arange(12).reshape(3,4)
print (a)
print (np.transpose(a))
.T
(transpose
的简写)
rollaxis
numpy.rollaxis(arr, axis, start)
其中:
* arr:要操作的数组;
* axis:沿着哪条轴向后滚动;
* start:默认以0轴开始,可以根据数组维度调整它的值
swapaxes
numpy.swapaxes(arr, axis1, axis2)
其中:
* arr:要操作的数组
* axis1:要交换的数据轴1
* axis2:要交换的数据轴2
import numpy as np
# 创建了三维的 ndarray
a = np.arange(27).reshape(3, 3, 3)
print(a)
# 对换0轴与2轴
print(np.swapaxes(a, 2, 0))
修改数组维度操作
函数名称 | 描述说明 |
---|---|
broadcast(arr1, arr2) | 返回值是数组被广播后的对象。 |
broadcast_to | 将数组广播为新的形状。 |
expand_dims | 扩展数组的形状。 |
squeeze | 从数组的形状中删除一维项。 |
broadcast
import numpy as np
a = np.array([[1], [2], [3]])
b = np.array([4, 5, 6])
# 对b广播a
d = np.broadcast(a, b)
# d它拥有 iterator 属性
r, c = d.iters # 将包含a和b的d对象的迭代器分别传给r和c
print(next(r), next(c))
print(next(r), next(c))
# 使用broadcast将a与b相加
e = np.broadcast(a, b)
f = np.empty(e.shape) # 创建e的数组维度用于创建新的数组
f.flat = [x + y for (x, y) in e] # 遍历e中的迭代器,并传给x和y,最后将x和y相加后传给f的迭代器
print(f)
print(a + b)
broadcast_to
该函数将数组广播到新形状中,它是在原始数组的基础上返回一个数组的只读视图。
- 如果新形状不符合Numpy的广播规则,会抛出
ValueError
异常。 ```python numpy.broadcast_to(array, shape, subok)
其中:
- array:要广播的数组
- shape:要广播的形状,参数类型是tulpe类型
- subok:可选参数,True表示子类为passed-through,否则返回的数组将被强制为base-class数组(默认)
a = np.arange(4).reshape(1, 4) print(“原数组”, a) print(‘调用 broadcast_to 函数之后:’) print(np.broadcast_to(a, (4, 4)))
<a name="kTBTY"></a>
### `expand_dims`(升维)
在**指定位置插入新的轴**,从而**扩展数组的维度**。
```python
numpy.expand_dims(arr, axis)
其中:
* arr:输入的数组
* axis:新轴插入的位置
import numpy as np
x = np.array(([1, 2], [3, 4])) # tuple将转换成数组类型
print('数组 x:')
print(x)
# 在 0 轴处插入新的轴
y = np.expand_dims(x, axis=0) # y被转换成了三维数组
print('数组 y:')
print(y)
print('数组 x 和 y 的形状:')
print(x.shape, y.shape)
squeeze
(降维)
删除数组中维度的一项。
numpy.squeeze(arr, axis)
其中:
* arr:输入的数组
* axis:取值为整数或整数的元组,用于指定需要删除的维度所在轴。若为None,则删除维度中所有为1的项
import numpy as np
a = np.arange(9).reshape(1, 3, 3)
print(a)
b = np.squeeze(a)
print(b)
print('数组 a 和 b 的形状:')
print(a.shape, b.shape)
连接和分割数组操作
类型 | 函数名称 | 描述说明 |
---|---|---|
连接数组方法 | concatenate | 沿指定轴连接两个或者多个相同形状的数组 |
stack | 沿着新的轴连接一系列数组 | |
hstack | 按水平顺序堆叠序列中数组(列方向) | |
vstack | 按垂直方向堆叠序列中数组(行方向) | |
分割数组方法 | split | 沿着指定轴,将一个数组分割为多个子数组 |
hsplit | 将一个数组水平分割为多个子数组(按列) | |
vsplit | 将一个数组垂直分割为多个子数组(按行) |
连接数组操作
concatenate
numpy.concatenate((a1, a2, ...), axis)
其中:
* a1,a2,...:表示一系列相同类型的数组
* axis:沿着该参数指定的轴连接数组,默认为0
import numpy as np
#创建数组a
a = np.array([[10,20],[30,40]])
print (a)
#创建数组b
b = np.array([[50,60],[70,80]])
print (b)
#沿轴 0 连接两个数组
print (np.concatenate((a,b)))
#沿轴 1 连接两个数组
print (np.concatenate((a,b),axis = 1))
# 输出结果如下:
"""
#a
[[10 20]
[30 40]]
#b
[[50 60]
[70 80]]
#axis=0沿着垂直方向
[[10 20]
[30 40]
[50 60]
[70 80]]
#axis=1沿着水平方向
[[10 20 50 60]
[30 40 70 80]]
"""
stack
hstack
vstack
import numpy as np
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
#垂直堆叠
c = np.vstack((a,b))
print (c)
分割数组操作
split
numpy.split(arr, indices_or_sections, axis)
其中:
* arr:要分割的数组
* indices_or_sections:若是一个整数,表示用该整数平均切分;若是一个数组,表示沿着轴切分的位置(左开右闭)
* axis:默认为0,表示横向切分;为1时,表示纵向切分
import numpy as np
a = np.arange(6)
# 原数组
print(a)
# 将数组分为二个形状大小相等的子数组
b = np.split(a, 2)
print(b)
# 将数组在一维数组中标明位置分割
c = np.split(a, [3, 4])
print(c)
# 输出结果如下:
"""
[0 1 2 3 4 5]
[array([0, 1, 2]), array([3, 4, 5])]
[array([0, 1, 2]), array([3]), array([4, 5])]
"""
hsplit
import numpy as np
# arr1数组
arr1 = np.floor(10 * np.random.random((2, 6)))
print(arr1)
# 拆分后数组
print(np.hsplit(arr1, 3))
# 输出结果如下:
"""
[[2. 3. 3. 7. 0. 5.]
[9. 5. 2. 9. 5. 9.]]
[array([[2., 3.],[9., 5.]]),
array([[3., 7.],[2., 9.]]),
array([[0., 5.],[5., 9.]])]
"""
vsplit
略。