繁体   English   中英

NumPy多维数组迭代如何工作? (有和没有nditer)

[英]How does NumPy multidimensional array iteration work? (With and without nditer)

注意:我不确定这是否重复 - 如果是,请告诉我(并关闭问题)。

如果有一个具有1维NumPy数组vector ,那么如果有人写一个for循环的形式:

for element in vector :
    print(element)

结果将打印NumPy数组的每个元素。

如果有一个二维NumPy数组matrix ,那么如果有人写一个for循环的形式:

for vector in matrix :
    print(vector)

结果将打印2维NumPy数组的每一行,即它将打印1维NumPy数组,并且它不会单独打印数组的每个元素。

但是,如果有人将for循环写为:

import numpy
for element in numpy.nditer(matrix) :
     print(element)

结果打印二维NumPy数组的每个元素。

问题:如果有一个三维NumPy数组, tensor会怎么样?

一个。 如果写一个for循环的形式:

for unknownType in tensor :
     print(unknownType)

这会打印构成二维NumPy(子) tensor阵列吗?

即,对于n维阵列NumPy的nArray ,确实for unknownType in nArray :遍历组成第(n-1)维NumPy的(子)的阵列nArray

如果写一个for循环的形式:

for unknownType in numpy.nditer(tensor) :
    print(unknownType)

这会打印出tensor元素吗? 或者它会打印成分二维NumPy(子)阵列tensor的组成1维NumPy(子)数组吗?

即n维NumPy数组nArrayfor unknownType in nditer(nArray) :迭代nArray的元素? 或者它是否在nArray的成分(n-1)维NumPy(子)数组的成分(n-2)维NumPy(子)数组上进行nArray

从名字nditer我不清楚,因为我不知道“nd”代表什么(“iter”显然是“迭代”的缩写)。 并且可能人们可以将这些元素视为“0维NumPy数组”,因此给我的二维NumPy数组的示例是模糊的。

我查看了np.nditer文档,但说实话,我不明白这些示例或者他们试图演示的内容 - 它似乎是程序员为程序员编写的(我不是)。

一个)

for x in arr:迭代数组的第一维。

In [233]: for x in np.arange(24).reshape((2,3,4)):
     ...:     print(x.shape)
     ...:     
(3, 4)
(3, 4)

我认为它是for x in list(arr):... 它将数组分成一个子数组列表。

b)

nditer控制迭代深度很棘手。 默认情况下,它会在元素级别进行迭代。 教程页面显示了使用缓冲区和顺序的一些技巧。 但我看到的最好的方法是使用ndindex

ndindex构造一个正确大小的虚拟数组,并执行multi_index迭代。

例如,迭代3d数组的前2个维度:

In [237]: arr = np.arange(24).reshape(2,3,4)
In [240]: for idx in np.ndindex(arr.shape[:2]):
     ...:     print(idx, arr[idx], arr[idx].sum())
     ...:      
(0, 0) [0 1 2 3] 6
(0, 1) [4 5 6 7] 22
(0, 2) [ 8  9 10 11] 38
(1, 0) [12 13 14 15] 54
(1, 1) [16 17 18 19] 70
(1, 2) [20 21 22 23] 86

我可以用同样的迭代

for i in range(2):
    for j in range(3):
         arr[i,j]...

要么

arr1 = arr.reshape(-1,4)
for ij in range(6):
    arr1[ij]....

速度基本相同 - 与同时在整个3d数组上工作的数组函数相比,或者采用某种axis参数的数据都比较差。

In [241]: arr.sum(axis=2)
Out[241]: 
array([[ 6, 22, 38],
       [54, 70, 86]])

numpy作为数组的类是np.ndarray 据推测, nditer就是这样命名的。 nditer是作为一种整合各种c级代码可以在数组上迭代的方式编写的,特别是几个可广播的代码。 np.nditer函数可以访问c级迭代器。 但是由于实际迭代仍然在Python代码中完成,所以几乎没有速度优势。

如果你只是使用for循环,那么迭代就在第一个维度上,如果数组只有一个维度,那么这将是元素,如果它是2D,它将是行,如果它是3D,它将迭代飞机,...

然而, nditer是ND(代表n维)迭代器。 它将迭代数组中的每个元素。 它(大致!)等同for item in your_array.ravel() (迭代数组的展平“视图”)。 对于1D数组,它迭代元素,对于2D数组,它首先迭代第一行中的元素,然后遍历第二行,依此类推。

请注意, nditer比它强大得多,它可以一次迭代多个数组,你可以缓冲迭代和许多其他东西。


但是对于NumPy,您通常希望使用for -loop或np.nditer 许多 “向量化”操作使得手动迭代(在大多数情况下)不必要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM