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

Chi*_*cht 3 python arrays for-loop numpy multidimensional-array

注意:我不确定这是否重复-请让我知道是否重复(并结束问题)。

如果有一个一维NumPy数组vector,则如果编写形式为以下形式的for循环:

for element in vector :
    print(element)
Run Code Online (Sandbox Code Playgroud)

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

如果有一个二维NumPy数组matrix,则如果编写一个for循环,其形式为:

for vector in matrix :
    print(vector)
Run Code Online (Sandbox Code Playgroud)

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

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

import numpy
for element in numpy.nditer(matrix) :
     print(element)
Run Code Online (Sandbox Code Playgroud)

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

问题:如果拥有3维NumPy数组会发生什么tensor?

一种。如果编写以下形式的for循环:

for unknownType in tensor :
     print(unknownType)
Run Code Online (Sandbox Code Playgroud)

这会打印出组成的二维NumPy(子)数组tensor吗?

即对于n维NumPy数组nArray,是否for unknownType in nArray :迭代组成n(N-1)维的NumPy(子)数组nArray?

b。如果编写以下形式的for循环:

for unknownType in numpy.nditer(tensor) :
    print(unknownType)
Run Code Online (Sandbox Code Playgroud)

这会印出的元素tensor吗?还是会打印组成的二维二维NumPy(子)数组的组成一维NumPy(子)数组tensor?

即对于n维NumPy数组nArray,是否for unknownType in nditer(nArray) :迭代的元素nArray?还是在元素的(n-1)维NumPy(子)数组的n(n-2)维数组中进行迭代nArray?

从名字上我不清楚nditer,因为我不知道“ nd”代表什么(“ iter”显然是“ iteration”的缩写)。并且大概可以将元素视为“ 0维NumPy数组”,因此为我提供的有关2维NumPy数组的示例是模棱两可的。

我看过np.nditer文档,但老实说,我不理解示例或示例试图演示的内容-似乎是由程序员为程序员编写的(我不是)。

hpa*_*ulj 5

一种)

for x in arr: 在数组的第一个维度上迭代。

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

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

b)

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

ndindex构造一个合适大小的虚拟数组,并进行multi_index迭代。

例如,要迭代3d数组的第1个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
Run Code Online (Sandbox Code Playgroud)

我可以用相同的迭代

for i in range(2):
    for j in range(3):
         arr[i,j]...
Run Code Online (Sandbox Code Playgroud)

要么

arr1 = arr.reshape(-1,4)
for ij in range(6):
    arr1[ij]....
Run Code Online (Sandbox Code Playgroud)

速度基本上是相同的-与同时处理整个3d数组或带有某种axis参数的数组函数相比,所有数组的速度都较差。

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

numpy作为数组的类是np.ndarray。大概nditer就是这样命名的。 nditer编写这种c代码是为了整合可以在数组上迭代的各种级别代码,尤其是一些可广播的代码。该np.nditer函数可以访问c级别迭代器。但是由于实际上迭代仍在Python代码中完成,因此几乎没有速度优势。


MSe*_*ert 4

如果您只使用for循环,则迭代将在第一个维度上进行,如果数组只有一个维度,则将是元素,如果是 2D,则将是行,如果是 3D,则将在平面上迭代,...

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

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


然而,对于 NumPy,您通常不想使用for-loop 或np.nditer. 有许多“矢量化”操作使得手动迭代(在大多数情况下)变得不必要。