【问题标题】:Iterating efficiently through indices of arbitrary order array通过任意顺序数组的索引有效地迭代
【发布时间】:2015-12-08 05:41:06
【问题描述】:

假设我有一个任意的变量阶 N 数组。例如: A 是一个 2x3x3 数组,是一个 3 阶数组,其三个索引具有 2,3 和 3 个维度。

我想有效地循环遍历每个元素。如果我先验地知道顺序,那么我可以(在 python 中)做类似的事情,

#for order 3 
import numpy as np
shape = np.shape(A)
i = 0
while i < shape[0]:
  j = 0
  while j < shape[1]:
    k = 0
    while k < shape[2]:
      #code using i,j,k
      k += 1
    j += 1
  i += 1

现在假设我不知道 A 的顺序,即我事先不知道 shape 的长度。如何以最快的速度置换数组的所有元素?

【问题讨论】:

  • 数组是否必须格式化为 numpy 数组?
  • 实际上想要实现什么?你可以做例如for indices in itertools.product(*map(range, shape)):,但这似乎不太可能是最好的方法。
  • 是否需要存储“#code using i,j,k”的结果?
  • @jonrsharpe:另一种选择:for indices in range(a.size): indices = np.unravel_index(i, a.shape)
  • 你可以递归地做,我在下面写了一个答案来说明如何做。

标签: python arrays loops indices


【解决方案1】:

有很多方法可以做到这一点,例如遍历a.ravel()a.flat。但是,在 Python 循环中遍历数组的每个元素永远不会特别有效。

【讨论】:

  • 迭代a.flat 将不允许基于原始 n 维数组中的位置(项目的 i、j、k 位置)执行操作。不过,它可以很好地为每个术语应用一些功能。
  • @AustinKootz 这可以通过迭代 enumerate(a.flat) 而不是 a.flat 轻松实现,就像您对普通 Python 列表所做的那样。
【解决方案2】:

我认为您选择首先置换哪个索引,选择第二个置换哪个索引等并不重要,因为您最里面的 while 语句将始终在 i、@ 的组合中执行一次987654322@ 和 k

【讨论】:

    【解决方案3】:

    如果是array = [[[1,2,3,4],[1,2]],[[1],[1,2,3]]]格式的数组

    您可以使用以下结构:

    array = [[[1,2,3,4],[1,2]],[[1],[1,2,3]]]
    indices = []
    def iter_array(array,indices):
        indices.append(0)
        for a in array:
            if isinstance(a[0],list):
                iter_array(a,indices)
            else:
                indices.append(0)
                for nonlist in a:
                    #do something using each element in indices
                    #print(indices)
                    indices.append(indices.pop()+1)
                indices.pop()
            indices.append(indices.pop()+1)
        indices.pop()
    
    iter_array(array,indices)
    

    这应该适用于通常的嵌套列表“数组”我不知道是否可以使用 numpy 的数组结构来模仿它。

    【讨论】:

    • OP 表示他们甚至不知道维度的数量(在帖子中称为“顺序”),因此您不知道要嵌套多少个循环。
    • 如果我们知道最大“订单”,我们可以在每个 for 语句前加上 if isinstance(array[i][j],list): 以允许它在适当的级别停止。
    • 我不太确定如何递归调用嵌套的 for 循环,但我觉得这是最好的方法。
    • 我已将其重写为递归。为了清楚起见,我可能会进行进一步的小修改
    【解决方案4】:

    如果您需要保留操作的结果(并假设它是 A 和 i,j,k 的函数),您会想要使用这样的东西:

    import itertools
    import numpy as np
    
    results = ( (position, code(A,position))
                  for indices in itertools.product(*(range(i) for i in np.shape(A))))
    

    然后你可以迭代结果得到每个位置的位置和代码的返回值。如果您需要多次访问结果,或者将生成器表达式转换为列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2021-05-16
      • 2011-01-24
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多