寻找常见子阵列的索引

时间:2011-09-20 22:16:57

标签: python arrays algorithm numpy

我有2个大的,未排序的数组(xyz坐标的结构化集合),我试图找到所有相同子阵列的位置(由3个坐标组成的公共点)。例如:

a = array([[0, 1, 2], [3, 4, 5]])
b = array([[3, 4, 5], [6, 7, 8]])

这里正确的子阵列是[3, 4, 5],但是不止一个相同的子阵列是可能的。 [0,1]的正确索引为a[1,0]b

我已经通过迭代一个数组的所有点并将它们与另一个数组的每个点进行比较来实现纯python方法,但这非常慢。

我的问题是,是否有一种有效的方法来查找两个数组的索引(最好是numpy,因为我需要数组进行进一步的计算)?也许是一个Rolling_window方法?

3 个答案:

答案 0 :(得分:2)

Python迭代的一般解决方案(不专用于numpy或数组)在线性平均时间内工作(O(n + m),n是子数组的数量,m是唯一子数组的数量):

a = [[0, 1, 2], [3, 4, 5]]
b = [[3, 4, 5], [6, 7, 8]]

from collections import defaultdict

indexmap = defaultdict(list)

for row, sublist in enumerate((a, b)):
    for column, item in enumerate(sublist):
        indexmap[tuple(item)].append((row, column))

repeats = dict((key, value) for key, value in indexmap.iteritems() if len(value) > 1)

给出

{(3, 4, 5): [(0, 1), (1, 0)]}

如果您不需要双行索引(列表中的索引和存储的索引中的索引),则可以将循环简化为

for row in (a, b):
    for column, item in enumerate(sublist):
        indexmap[tuple(item)].append(column)

a将在b之前处理,任何重复项都会自动按行编号:

{(3, 4, 5): [1, 0]}

repeats[key][rownum]返回该行的列索引。

答案 1 :(得分:1)

我做了一些进一步的实验,发现了一种解决这个问题的特定方法:

import numpy as np

a = np.arange(24).reshape(2,4,3)
b = np.arange(24, 36).reshape(2,2,3)

数组b从a:

接收2个条目
b[1,0] = a[0,1]
b[0,1] = a[1,1]

查找常用条目:

c = np.in1d(a, b).reshape(a.shape)
d = np.in1d(b, a).reshape(b.shape)

检查所有3个坐标中公共条目的位置:

indexesC = np.where(c[:,:,0] & c[:,:,1] & c[:,:,2])
indexesD = np.where(d[:,:,0] & d[:,:,1] & d[:,:,2])

答案 2 :(得分:0)

您可以将每个子数组映射到哈希表中的位置索引吗?所以基本上,你改变了你的数据结构。在线性时间O(n)之后,其中n是最大哈希哈希表的大小,在一个循环中,您可以O(1)查询每个哈希表,并找出是否在两个或更多个中存在相同的子阵列哈希表。