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

时间:2015-07-01 03:06:57

标签: python arrays numpy iterator

我有一个numpy中的多维数组(例如4D),我想指定numpy迭代器的深度,我不知道该怎么做呢?

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

我确实想使用迭代器而不是双循环,我想使用numpy而不是其他工具,如字典和pandas。

因此,我希望这段代码输出[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]

1 个答案:

答案 0 :(得分: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部分是最好的部分。