【问题标题】:Iterating over 3d array in Python在 Python 中迭代 3d 数组
【发布时间】:2020-03-18 07:54:43
【问题描述】:

我有一个形状为 (7,4,6​​) 的 3d 矩阵,其中 4x6 是(行 x 列),7 是帧/层数。我想在 4x6 的每个值上迭代每一层。但是,如果我将循环的顺序从(帧、行、列)更改为(行、列、帧),则循环总是会给出索引错误。我使用的代码是:

>>> array.shape
(7, 4, 6)
>>> for i in range(0,4):
...     for j in range(0,6):
...         for k in range(0,7):
...             print(array[i][j][k])

我希望框架成为最内层的循环,但在运行上述代码时出现索引错误。有关如何修改上述代码的任何建议?

【问题讨论】:

  • 首先0 是多余的。您可以简单地写入 range(4)、range(5) 和 range(7)。其次,我认为顺序需要是 7,4,6​​ 而不是你写的
  • 除了下面的答案,您还可以使用np.ravel 将数组“展平”为一维。
  • ^ 或 array.flatten() 本身。
  • 你不应该使用这么多的括号。请改用print(array[k ,i ,j]),因为它更具可读性并且更快。

标签: python multidimensional-array


【解决方案1】:

您应该使用以下内容:

>>> array.shape
(7, 4, 6)
>>> for j in range(4):
...     for k in range(6):
...         for i in range(7):
...            print(array[i][j][k])

您在原始代码中使用了错误的索引器。

【讨论】:

    【解决方案2】:

    numpy 有一个功能:np.nditer:

    >>> array = np.random.randint(0, 10, size = (3,4,5))
    >>> array.shape
    (3, 4, 5)
    >>> array
    array([[[8, 8, 0, 6, 0],
            [9, 4, 6, 6, 1],
            [4, 3, 1, 3, 6],
            [2, 4, 4, 3, 9]],
    
           [[3, 5, 3, 9, 6],
            [8, 0, 8, 5, 3],
            [4, 8, 6, 2, 7],
            [2, 7, 1, 8, 4]],
    
           [[5, 7, 5, 6, 7],
            [7, 4, 2, 7, 0],
            [5, 6, 7, 9, 7],
            [7, 2, 7, 7, 4]]])
    >>> for elem in np.nditer(array):
    ...     print(elem, end=' ')
    
    8 8 0 6 0 9 4 6 6 1 4 3 1 3 6 2 4 4 3 9 3 5 3 9 6 8 0 8 5 3 4 8 6 2 7 2 7 1 8 4 5 7 5 6 7 7 4 2 7 0 5 6 7 9 7 7 2 7 7 4 
    

    如果您想以不同的顺序打印它们,请使用order 标志:

    >>> for idx in np.nditer(array, order='F'):
    ...     print(idx, end = ' ')
    8 3 5 9 8 7 4 4 5 2 2 7 8 5 7 4 0 4 3 8 6 4 7 2 0 3 5 6 8 2 1 6 7 4 1 7 6 9 6 6 5 7 3 2 9 3 8 7 0 6 7 1 3 0 6 7 7 9 4 4
    

    如果你想要indices,你可以使用np.ndindex

    >>> for idx in np.ndindex(array.shape):
    ...     print(array[idx], end=' ')
    8 8 0 6 0 9 4 6 6 1 4 3 1 3 6 2 4 4 3 9 3 5 3 9 6 8 0 8 5 3 4 8 6 2 7 2 7 1 8 4 5 7 5 6 7 7 4 2 7 0 5 6 7 9 7 7 2 7 7 4 
    

    np.ndindex 将索引作为元组给出:

    >>> for idx in np.ndindex(array.shape):
    ...     print(idx, end=' ')
    (0, 0, 0) (0, 0, 1) (0, 0, 2) (0, 0, 3) (0, 0, 4) (0, 1, 0) (0, 1, 1) (0, 1, 2) (0, 1, 3) (0, 1, 4) (0, 2, 0) (0, 2, 1) (0, 2, 2) (0, 2, 3) (0, 2, 4) (0, 3, 0) (0, 3, 1) (0, 3, 2) (0, 3, 3) (0, 3, 4) (1, 0, 0) (1, 0, 1) (1, 0, 2) (1, 0, 3) (1, 0, 4) (1, 1, 0) (1, 1, 1) (1, 1, 2) (1, 1, 3) (1, 1, 4) (1, 2, 0) (1, 2, 1) (1, 2, 2) (1, 2, 3) (1, 2, 4) (1, 3, 0) (1, 3, 1) (1, 3, 2) (1, 3, 3) (1, 3, 4) (2, 0, 0) (2, 0, 1) (2, 0, 2) (2, 0, 3) (2, 0, 4) (2, 1, 0) (2, 1, 1) (2, 1, 2) (2, 1, 3) (2, 1, 4) (2, 2, 0) (2, 2, 1) (2, 2, 2) (2, 2, 3) (2, 2, 4) (2, 3, 0) (2, 3, 1) (2, 3, 2) (2, 3, 3) (2, 3, 4)
    

    【讨论】:

    • 嗨 Sayandip,谢谢您的建议。我所要做的就是更改订单标志以获得所需的订单:)
    • @rohitnarayanan 很高兴它有帮助。如果您认为它回答了您的问题,您可以考虑将其标记为已接受 :)
    【解决方案3】:

    使用 itertools 模块可能是一种更优雅和 Pythonic 的方式。

    from itertools import product
    
    def using_itertools(array):
        X, Y, Z = array.shape
        for x, y, z in product(range(X), range(Y), range(Z)):
            print(array[x,y,z])
    
    def using_forloop(array):
        X, Y, Z = array.shape
        for k in range(Z):
            for j in range(Y):
                for i in range(X):
                    print(array[i][j][k])
    

    虽然第一种方法看起来很干净,但在速度方面我发现两者都相似

    【讨论】:

      猜你喜欢
      • 2015-02-22
      • 1970-01-01
      • 2014-07-09
      • 2010-11-21
      • 2019-01-25
      • 2020-03-29
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      相关资源
      最近更新 更多