numpy迭代数组nditer

1 逐个访问数组元素

使用nditer可以完成逐个访问数组中的元素。

a = np.arange(4).reshape(2, 2)
for i in a:
    print(i)
for i in np.nditer(a):
    print(i)

结果:

[0 1]
[2 3]
0
1
2
3

对于一维数组结果一样,但是多维就有区别了

2 控制迭代顺序

nditer对象提供了一个order参数来控制迭代顺序。其参数order有三个可选参数:K,F,C
具有上述行为的默认值是order ='K’以保持现有订单。 对于C顺序,可以使用order ='C’覆盖它,对于Fortran顺序,可以使用order ='F’覆盖它。
其中“K”是默认的,其结果与与原来的没有区别,逐个读取元素;
“C”:C order,即行序优先;;
“F”:Fortran order,即列序优先;

2.1二维
a = np.arange(6).reshape(2, 3)
print(a)
for i in np.nditer(a, order='C'):
    print(i)
print("---------")
for i in np.nditer(a, order='F'):
    print(i)
print("---------")
for i in np.nditer(a, order='K'):
    print(i)

结果:

[[0 1 2]
 [3 4 5]]
0
1
2
3
4
5
---------
0
3
1
4
2
5
---------
0
1
2
3
4
5

可以看出二维情况下"F"参数确实就是可以看过按列读取元素

2.2三维
a = np.arange(18).reshape(2, 3, 3)
print(a)
for i in np.nditer(a, order='C'):
    print(i)
print("---------")
for i in np.nditer(a, order='F'):
    print(i)
print("---------")
for i in np.nditer(a, order='K'):
    print(i)

结果:

[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]]
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---------
0
9
3
12
6
15
1
10
4
13
7
16
2
11
5
14
8
17
---------
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

注意三维数组列序优先时的读取顺序。

3 修改数组值

并不推荐这种方法来修改数组值,可以作为参考
默认情况下,nditer将输入数组视为只读对象。 要修改数组元素,必须指定读写或只写模式。 这是用每操作数标志控制的。
Python中的常规赋值只是更改本地或全局变量字典中的引用,而不是修改现有变量。 这意味着简单地分配给x不会将值放入数组的元素中,而是将x作为数组元素引用切换为对指定值的引用。 要实际修改数组的元素,x应该用省略号索引。

a = np.arange(6).reshape(2, 3)
for x in np.nditer(a, op_flags=['readwrite']):
    x[...] = 2*x
print(a)

[[ 0  2  4]
 [ 6  8 10]]

4 使用外部循环

在目前为止的所有示例中,a的元素由迭代器一次提供一个,因为所有循环逻辑都是迭代器的内部逻辑。 虽然这很简单方便,但效率不高。 更好的方法是将一维最内层循环移动到迭代器外部的代码中。 这样,NumPy的矢量化操作可以用在被访问元素的较大块上。

nditer将尝试提供尽可能大的内部循环块。 通过强制’C’和’F’顺序,我们得到不同的外部循环大小。 通过指定迭代器标志来启用此模式。

a = np.arange(6).reshape(2, 3)
for x in np.nditer(a, flags=['external_loop'], order='C'):
    print(x)
print("--------------")
for x in np.nditer(a, flags=['external_loop'], order='F'):
    print(x)

结果:注意行序优先中输出的一个数组,而不是一个个的数字元素

[0 1 2 3 4 5]
--------------
[0 3]
[1 4]
[2 5]

5 跟踪索引或多索引

在迭代期间,你可能希望在计算中使用当前元素的索引。 例如,你可能希望按内存顺序访问数组的元素,然后使用C顺序,Fortran顺序或多维索引来查找不同数组中的值。

5.1multi_index

下面代码中order参数根据自己需要选择,也可以不写默认按行逐个读取元素

a = np.arange(6).reshape(2, 3)
it = np.nditer(a, flags=['multi_index'], order="F")
while not it.finished:
    print("%d < %s>" %(it[0], it.multi_index))
    it.iternext()

结果: it.multi_index代表元素的索引,以元组形式输出

0 < (0, 0)>
3 < (1, 0)>
1 < (0, 1)>
4 < (1, 1)>
2 < (0, 2)>
5 < (1, 2)>
5.2 f_index
a = np.arange(6).reshape(2, 3)
it = np.nditer(a, flags=['f_index'])
while not it.finished:
    print("%d < %d>" % (it[0], it.index))
    it.iternext()

结果:索引的编号,以列序优先

0 < 0>
1 < 2>
2 < 4>
3 < 1>
4 < 3>
5 < 5>

6 缓冲数组元素

通过启用缓冲模式,迭代器提供给内部循环的块可以变得更大,从而显着减少Python解释器的开销。 在强制Fortran迭代顺序的示例中,当启用缓冲时,内部循环可以一次性查看所有元素。

a = np.arange(6).reshape(2, 3)
for x in np.nditer(a, flags=['external_loop','buffered'], order='F'):
   print(x)

输出:

[0 3 1 4 2 5]

7 广播数组迭代

代码:

a = np.arange(3)
b = np.arange(6).reshape(2,3)
for x, y in np.nditer([a,b]):
    print("%d:%d" % (x,y))

输出:

0:0
1:1
2:2
0:3
1:4
2:5
  • 14
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值