【问题标题】:Efficient way to loop through orthodiagonal indices in order按顺序循环遍历正交索引的有效方法
【发布时间】:2020-06-23 04:24:06
【问题描述】:

我想找到一种更好的方法来按顺序遍历正交索引,我目前正在使用 numpy,但我认为我进行了不必要的函数调用。

import numpy as np

len_x, len_y = 50, 50 #they don't have to equal
index_arr = np.add.outer(np.arange(len_x), np.arange(len_y))

目前,我正在这样循环:

for i in range(np.max(index_arr)):
    orthodiag_indices = zip(*np.where(index_arr == i))
        for index in orthodiag_indices:
            # DO FUNCTION OF index #

我有一个索引元组的任意函数,index 和此循环之外的其他参数。感觉我不需要第二个for 循环,我应该能够在一个循环中完成整个事情。最重要的是,我从zip(*np.where(index_arr == i)) 为每个i 进行了很多函数调用。最有效的方法是什么?

编辑:应该提到该函数按顺序应用于index_arr == i 很重要,即它首先执行 0,然后执行 1,然后执行 2 等(第二个循环的顺序无关紧要)。

编辑 2:我想我想要的是一种获取索引 [(0,0), (0,1), (1,0), (2,0), (1,1), ( 2,0), ...] 有效。我认为我不能应用矢量化函数,因为我正在填充 np.zeros((len_x, len_y)) 数组,然后返回第一次编辑,顺序很重要。

【问题讨论】:

  • 更多可能有用的上下文:“函数”正在填充一个 numpy 数组,该数组在 0 处启动:output_arr = np.zeros((len_x, len_y)),该函数从上方作用于 index 以填充 output_arr .
  • Related。专门解决此问题的更有效方法可能涉及scipy.ndimage.labelled_comprehension
  • 嗨,这很好,但也许我没有提供足够的信息。似乎这个解决方案假定数组元素的输出独立。不幸的是,在i=2 填充我的空output_arr 取决于i=1 发生的事情,这取决于i=0。我想如果这就是你的意思,可以对orthodiag_indices 上的函数进行矢量化?
  • 我建议的解决方案确实假设独立。除此之外,还有两种可能的情况可以想到:要么f(n) 仅依赖于f(k) 的实现k<n,要么f(n) 不能从f(0):f(n-1) 确定。在前一种情况下,您可以通过假设 f 仅在 1:(n-1)^2 上取值来模仿独立性。否则,如果不了解更多关于函数f 的信息,就很难设计优化。

标签: python-3.x performance numpy numpy-ndarray


【解决方案1】:

您可以使用tril/triu_indices。由于(前)内部循环的顺序无关紧要,尺寸可以根据需要交换,我假设L>=S

L,S = 4,3

a0,a1 = np.tril_indices(L,0,S)
b0,b1 = np.triu_indices(S,1)
C0 = np.concatenate([a0-a1,b0+L-b1])
C1 = np.concatenate([a1,b1])
*zip(C0,C1),
# ((0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (3, 0), (2, 1), (1, 2), (3, 1), (2, 2), (3, 2))

【讨论】:

  • 谢谢。这并没有完全遍历整个网格,对于x_dim, y_dim=4,2,最后一个元素应该是(3,1),而不是遍历“一半网格”。
  • @ggmp 已修复,但不像以前那么简洁了。
【解决方案2】:

我认为itertools.product() 在这里会派上用场

import itertools as it
x,y = 2,3
a=list(it.product(range(x),range(y))

这给a

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

如果您需要它们,那么,

b=np.argsort(np.sum(a,1))
np.array(a)[b]

给出,

array([[0, 0],
   [0, 1],
   [1, 0],
   [0, 2],
   [1, 1],
   [1, 2]])

希望有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多