python - 如何在numpy中指定迭代器的深度?

我在numpy中有一个多维数组(例如4D),我想指定numpy迭代器的深度,我不确定如何执行此操作?

例如,假设我有一个4D numpy数组,并且我想仅从2D级别的迭代器中获取元素(因此,每个项也将是2D)。有没有办法在迭代器中指定这种深度?

我确实确实想使用迭代器来代替双循环,并且我想使用numpy来代替字典和熊猫等其他工具。

因此,我希望这段代码输出[1 2]而不是1,2 ...

x = np.array(\
(\
\
(\
(np.array([1,2]), np.array([1,2])),\
(np.array([1,2]), np.array([1,2]))\
),\
\
(\
(np.array([1,2]), np.array([1,2])),\
(np.array([1,2]), np.array([1,2]))\
)\
\
)
, dtype = np.ndarray)

for i in np.nditer(x, flags = ["refs_ok"]):
     print i


给我:

1
2
1
2
1
2
1
2
1
2
1
2
1
2
1
2


代替:

[1 2]
[1 2]
[1 2]
[1 2]
[1 2]
[1 2]
[1 2]
[1 2]

最佳答案

np.ndindex可以很好地遍历指定的尺寸。

您的x是4d object数组,dtype=ndarray变为dtype=object。尽管元组的大小相同,但元素实际上只是标量,而不是数组。

In [385]: x
Out[385]: 
array([[[[1, 2],
         [1, 2]],

        [[1, 2],
         [1, 2]]],


       [[[1, 2],
         [1, 2]],

        [[1, 2],
         [1, 2]]]], dtype=object)

In [386]: x.shape
Out[386]: (2, 2, 2, 2)


在任何情况下, np.ndindex都会生成将在给定形状的数组上迭代的索引。

In [387]: for i,j in np.ndindex(x.shape[:2]):
    print(i,j)       
    print(x[i,j])
   .....:     
0 0
[[1 2]
 [1 2]]
0 1
[[1 2]
 [1 2]]
1 0
[[1 2]
 [1 2]]
1 1
[[1 2]
 [1 2]]


ndindex的关键片段用于生成正确大小的伪矩阵的 as_strided,并使用 nditer模式生成 multi_index

此用法的先前示例:

https://stackoverflow.com/a/28727290/901925

Iterating over first d axes of numpy array

有关尝试创建数组数组(不仅仅是数字的高维数组)的更多信息:

Convert a numpy array to an array of numpy arrays

要使 x确实是一个数组数组,您需要执行以下操作:

In [397]: x=np.zeros((2,2,2),dtype=object)
In [398]: for ijk in np.ndindex(x.shape):
             x[ijk] = np.array([1,2])


In [399]: x
Out[399]: 
array([[[array([1, 2]), array([1, 2])],
        [array([1, 2]), array([1, 2])]],

       [[array([1, 2]), array([1, 2])],
        [array([1, 2]), array([1, 2])]]], dtype=object)




另一种选择是重塑初始尺寸,因此您可以对这些尺寸进行平面迭代:

for i in x.reshape(-1,2):
    print(i)


nditer(以及扩展名 ndindex)被描述为有效的,但是更适用于 C/cython的使用。在纯Python代码中,迭代机制并不重要。迭代主体中的动作通常需要更多时间。如需要在多个数组上进行坐标迭代时,如 nditer所示, out[...] = a[...] * b[...]也是最佳选择。仅仅迭代一个数组并没有什么特别的。

http://docs.scipy.org/doc/numpy-dev/reference/arrays.nditer.html

是一个很好的 nditer教程。最后的cython部分是最好的部分。