【问题标题】:Optimizing two-dimensional arrays优化二维数组
【发布时间】:2015-08-27 23:28:07
【问题描述】:

我正在使用 Python 2.7 进行编码。 我有两个坐标元组的二维数组。

array1 = [[[00_RA,00_DEC] [01_RA,01_DEC] ... [0N_RA,0N_DEC]]
          [[10_RA,10_DEC] [11_RA,11_DEC] ... [1N_RA,1N_DEC]]
          ...
          [[M0_RA,M0_DEC] [M1_RA,M1_DEC] ... [MN_RA,MN_DEC]]]

array2 = [[[00_ra,00_dec] [01_ra,01_dec] ... [0n_ra,0n_dec]]
          [[10_ra,10_dec] [11_ra,11_dec] ... [1n_ra,1n_dec]]
          ...
          [[m0_ra,m0_dec] [m1_ra,m1_dec] ... [mn_ra,mn_dec]]]

我想找到出现在另一个数组中的两个数组条目的坐标。 以下代码有效,但需要很长时间才能运行,尤其是 M,N,m,n 通常在 100-1000 之间。

indices = []
for M in xrange(len(array1)):
    array1_row = array1[M]
    for N in xrange(len(array1_row)):
        array1_coord = array1_row[N]
        RA = array1_coord[0]
        DEC = array1_coord[1]
        for m in xrange(len(array2)):
            array2_row = array2[m]
            for n in xrange(len(array2_row)):
                array2_coord = array2_row[n]
                ra = array2_coord[0]
                dec = array2_coord[1]
                if ra == RA and dec == DEC:
                    indices.append((M,N,m,n))

我正在尝试使用列表推导来优化它。我认为以下应该有效:

indices = [(M,N,m,n) for M in xrange(len(array1)) for N in xrange(len(array1[M])) for m in xrange(len(array2)) for n in xrange(len(array2[m])) if array1[M,N,0] == array2[m,n,0] and array1[M,N,1] == array2[m,n,1]]

这需要更长的时间才能运行,即使是单行也是如此。 (我在运行几个小时后停止了它,但在那段时间没有抛出错误)。 我是否以最好的方式优化它?我该怎么做才能加快速度?

【问题讨论】:

  • 您是指数组中的任何位置还是同一索引处?
  • 我的意思是如果array1中的给定坐标(RA,DEC)出现在array2中的任何位置(ra,dec),那么我想获取array1中该坐标的索引和坐标的索引在array2中。
  • 您可以对两个数组进行传递,并构建一个辅助数据结构(列表可以),该结构将包含数组中的数据及其索引,按数组数据排序。然后,在两个列表中搜索相同的数据将是一个简单的操作。

标签: python arrays optimization multidimensional-array list-comprehension


【解决方案1】:

提供的代码具有 θ(M * N * m * n) 的运行时复杂度。可以通过使用集合将其简化为 θ(M * N + m * n)。这可以通过首先散列集合中第一个数组的值,然后检查其他数组的值是否已经存在于集合中来完成。

需要注意的是,您不能在集合中添加列表(??它们是可变的)因此您必须在添加到集合之前将它们转换为元组。

【讨论】:

  • 感谢您的洞察力。我认为这就是 FMc 在下面的示例答案中所做的。这肯定比我预期的要快得多。
【解决方案2】:

您需要不同的数据结构来进行快速查找:dict 而不是 list。这是一个例子:

array1 = [
    [[1,2], [1,5]],
    [[3,2], [7,5]],
]

array2 = [
    [[3,2], [9,9]],
    [[1,2], [1,5]],
]

lookup = {}

for r, row in enumerate(array1):
    for c, val in enumerate(row):
        pair = tuple(val)
        lookup[pair] = (r, c)

for r, row in enumerate(array2):
    for c, val in enumerate(row):
        pair = tuple(val)
        if pair in lookup:
            print dict(
                pair = pair, 
                array2_indexes = (r, c),
                array1_indexes = lookup[pair],
            )

输出:

{'array1_indexes': (1, 0), 'pair': (3, 2), 'array2_indexes': (0, 0)}
{'array1_indexes': (0, 0), 'pair': (1, 2), 'array2_indexes': (1, 0)}
{'array1_indexes': (0, 1), 'pair': (1, 5), 'array2_indexes': (1, 1)}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2018-02-26
    相关资源
    最近更新 更多