NumPy学习第七课:数组的迭代

73 阅读4分钟

前言

什么是数组的迭代?其实说白了,就是将数组的元素一个个的进行循环输出,NumPy的迭代数组其实跟之前我们 学习Python基础的时候的数组循环差不多吧。

如果没有看之前的可以点击查看Pyton专栏中的:Python学习之循环

那么我们就开始今天学习了。

迭代数组方式

1、numpy.nditer

我们直接就在编辑器中进行测试就行了,这章比较简单一点儿。

image.png

参考代码:

import numpy as np

# 使用 arange() 函数创建一个 2X3 数组,并使用 nditer 对它进行迭代
a = np.arange(6).reshape(2, 3)
print('原始数组是:')
print(a)
print('\n')
print('迭代输出元素:')
for x in np.nditer(a):
    print(x, end=", ")
print('\n')

# 输出结果
# 原始数组是:
# [[0 1 2]
#  [3 4 5]]
# 
# 
# 迭代输出元素:
# 0, 1, 2, 3, 4, 5, 

有的人有洁癖,如果非要给输出换一种风格,那也不是不可能,Numpy已经给我们提供了,请看:

image.png

参考代码:

import numpy as np


# 可以通过显式设置,来强制 nditer 对象使用某种顺序:
b = np.arange(0, 60, 5)
b = b.reshape(3, 4)
print('原始数组是:')
print(b)
print('\n')
print('以C风格顺序排序:')
for x in np.nditer(b, order = 'C'):
    print(x, end=", ")
print('\n')
print('以F风格顺序排序:')
for x in np.nditer(b, order='F'):
    print(x, end=", ")


# 输出结果:
# 原始数组是:
# [[ 0  5 10 15]
#  [20 25 30 35]
#  [40 45 50 55]]
# 
# 
# 以C风格顺序排序:
# 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 
# 
# 以F风格顺序排序:
# 0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 

nditer 对象还有另一个可选参数 op_flags

image.png

参考代码:

import numpy as np

# nditer 对象有另一个可选参数 op_flags。
# 默认情况下,nditer 将视待迭代遍历的数组为只读对象(read-only),
# 为了在遍历数组的同时,实现对数组元素值的修改,
# 必须指定 readwrite 或者 writeonly 的模式
c = np.arange(0, 60, 5)
c = c.reshape(3, 4)
print('原始数组是:')
print(c)
print('\n')
for x in np.nditer(c, op_flags = ['readwrite']):
    x[...] = 2*x
print('修改后的数组是:')
print(c)

# 输出结果
# 原始数组是:
# [[ 0  5 10 15]
#  [20 25 30 35]
#  [40 45 50 55]]
# 
# 
# 修改后的数组是:
# [[  0  10  20  30]
#  [ 40  50  60  70]
#  [ 80  90 100 110]]

nditer 对象的另一个可选参数 flags 参数

flags参数的参数值有许多,这边就一一例举一下吧

参数值描述
c_index可以跟踪 C 顺序的索引
f_index可以跟踪 F 顺序的索引
multi_index每次迭代可以跟踪一种索引类型
external_loop给出的值是具有多个值的一维数组,而不是零维数组

image.png

参考代码:


import numpy as np


# nditer类的构造器 flags 参数的使用
x = np.arange(0, 30, 2).reshape(3, 5)
print('原始数组')
print(x)
print('\n')
# 使用c_index
# for x in np.nditer(x, flags=['c_index'], order='F'):
#     print(x, end=",")
# 输出结果
# 0,10,20,2,12,22,4,14,24,6,16,26,8,18,28,


# # 使用f_index
# for x in np.nditer(x, flags=['f_index'], order='F'):
#     print(x, end=",")
# 输出结果:0,10,20,2,12,22,4,14,24,6,16,26,8,18,28,


#
# # 使用multi_index
# for x in np.nditer(x, flags=['multi_index'], order='F'):
#     print(x, end=",")
# 输出结果:0,10,20,2,12,22,4,14,24,6,16,26,8,18,28,


# # 使用external_loop
for x in np.nditer(x, flags=['external_loop'], order='F'):
    print(x, end=",")

# 输出结果: [ 0 10 20],[ 2 12 22],[ 4 14 24],[ 6 16 26],[ 8 18 28],

上节课我们还学习了广播,那么广播能不能迭代呢?那肯定是可以的了。

image.png

参考代码


import numpy as np

# 广播迭代

# 当运算中的 2 个数组的形状不同时,numpy 将自动触发广播机制
# 4x3 的二维数组与长为 3 的一维数组相加,等效于把数组 e 在二维上重复 4 次再运算
d = np.array([[0, 0, 0], [10, 10, 10], [20, 20, 20], [30, 30, 30]])
e = np.array([0, 1, 2])

# 迭代后的数组:
for x, y in np.nditer([d, e]):
    print("%d:%d" %( x, y),end=",")

# 输出结果: 0:0,0:1,0:2,10:0,10:1,10:2,20:0,20:1,20:2,30:0,30:1,30:2,