遍历Numpy数组元素

时间:2020-05-31 14:40:01

标签: python numpy numpy-ndarray

在Python中遍历Numpy数组的每个元素的循环是否存在更易读的方式?我想出了以下代码,但它看起来很麻烦而且可读性很差:

import numpy as np
arr01 = np.random.randint(1,10,(3,3))
for i in range(0,(np.shape(arr01[0])[0]+1)):
    for j in range(0,(np.shape(arr01[1])[0]+1)):
        print (arr01[i,j])

我可以使其更加明确,例如:

import numpy as np
arr01 = np.random.randint(1,10,(3,3))
rows = np.shape(arr01[0])[0]
cols = np.shape(arr01[1])[0]
for i in range(0, (rows + 1)):
    for j in range(0, (cols + 1)):
        print (arr01[i,j])

但是,与其他语言相比,这似乎还比较麻烦,例如,可以读取VBA中的等效代码(假设已经填充了数组):

dim i, j as integer
for i = lbound(arr01,1) to ubound(arr01,1)
   for j = lbound(arr01,2) to ubound(arr01,2)
       msgBox arr01(i, j)
   next j
next i

非常感谢您的提示和提示

最诚挚的问候

J。

2 个答案:

答案 0 :(得分:2)

如果不需要索引值,则应使用内置函数nditer

for elem in np.nditer(arr01):
    print(elem)

编辑:如果您需要索引(作为2D表的元组),则:

for index, elem in np.ndenumerate(arr01):
    print(index, elem)

答案 1 :(得分:2)

似乎您已经跳过了一些Python入门章节。有了列表,有几种简单的迭代方法:

In [1]: alist = ['a','b','c']                                                   
In [2]: for i in alist: print(i)        # on the list itself                                                
a
b
c
In [3]: len(alist)                                                              
Out[3]: 3
In [4]: for i in range(len(alist)): print(i,alist[i])  # index is ok                 
0 a
1 b
2 c
In [5]: for i,v in enumerate(alist): print(i,v)   # but enumerate is simpler            
0 a
1 b
2 c

注意索引。 range(3)就足够了。 alist[3]产生错误。

In [6]: arr = np.arange(6).reshape(2,3)                                         
In [7]: arr                                                                     
Out[7]: 
array([[0, 1, 2],
       [3, 4, 5]])
In [8]: for row in arr: 
   ...:     for col in row: 
   ...:         print(row,col) 
   ...:                                                                         
[0 1 2] 0
[0 1 2] 1
[0 1 2] 2
[3 4 5] 3
[3 4 5] 4
[3 4 5] 5

shape是一个元组。这样,行数为arr.shape[0],列数为arr.shape[1]。或者,您可以一次“解压缩”这两个文件:

In [9]: arr.shape                                                               
Out[9]: (2, 3)
In [10]: n,m = arr.shape                                                        
In [11]: [arr[i,j] for i in range(n) for j in range(m)]                         
Out[11]: [0, 1, 2, 3, 4, 5]

但是我们可以使用ravel和到列表的可选转换得到相同的平面值列表:

In [12]: arr.ravel()                                                            
Out[12]: array([0, 1, 2, 3, 4, 5])
In [13]: arr.ravel().tolist()                                                   
Out[13]: [0, 1, 2, 3, 4, 5]

但是通常对于numpy数组,您根本不应该进行迭代。了解足够的numpy基础知识,以便您可以处理整个数组,而不是元素。

如另一个答案所示,

nditer可用于以平坦的方式遍历数组,但是有关它的许多细节很容易使初学者感到困惑。 nditer有几个简介页,但应完整阅读。通常我不鼓励使用它。

In [14]: for i in np.nditer(arr): 
    ...:     print(i, type(i), i.shape) 
    ...:                                                                        
0 <class 'numpy.ndarray'> ()        # this element is a 0d array, not a scalar integer
1 <class 'numpy.ndarray'> ()
2 <class 'numpy.ndarray'> ()
... 

ndenumeratetolist上进行迭代会产生不同类型的元素。如果您尝试做的事情不仅仅是显示值,则类型可能很重要,因此请小心。

In [15]: list(np.ndenumerate(arr))                                              
Out[15]: [((0, 0), 0), ((0, 1), 1), ((0, 2), 2), ((1, 0), 3), ((1, 1), 4), ((1, 2), 5)]
In [16]: for ij, v in np.ndenumerate(arr): 
    ...:     print(ij, v, type(v)) 
    ...:                                                                        
(0, 0) 0 <class 'numpy.int64'>
(0, 1) 1 <class 'numpy.int64'>
...
In [17]: for i, v in enumerate(arr.ravel().tolist()): 
    ...:     print(i, v, type(v)) 
    ...:                                                                        
0 0 <class 'int'>
1 1 <class 'int'>
...