按行比较二维数组

Compare 2D arrays row-wise

此问题是由 3D 非结构化网格的空间分析引起的。 我有 2 个二维数组进行比较,每个数组都有 3 列用于 xyz 坐标。 其中一个数组是引用,另一个是根据它求值的(它是 CKde 树查询引用数组的结果)。最后我想要引用的匹配行数。 我试图找到一个数组连接解决方​​案,但我迷失在不同的维度

reference=np.array([[0,1,33],[0,33,36],[0,2,36],[1, 33, 34]])
query= np.array([[0,1,33],[0,1,33],[1, 33, 34],[0,33,36],[0,33,36],[0,1,33],[0,33,36]])

我要去的地方有点风格

filter=reference[:,:,None]==query.all(axis=0)
result = filter.sum(axis=1)

但我找不到能够比较 2 个数组的行的正确广播方式。 结果应该是:

np.array([3,3,0,1])

你需要广播这两个数组。由于您无法直接比较一维数组,因此您首先需要在最后一个维度上使用 all 进行缩减。然后你可以用总和 sum 来计算匹配的行。这是结果代码:

(reference[None,:,:] == query[:,None,:]).all(axis=2).sum(axis=0)

话虽这么说,但对于较大的阵列而言,此解决方案并不是最有效的。事实上,对于 referencen 大小的 m 行和 query 中的 k 行,解决方案的复杂性是 O(n m k) 而最佳解决方案是 O(n m + n k)。这可以使用 哈希映射 (又名 dict)来实现。这个想法是将 reference 数组的行放入哈希映射中,并将关联值设置为 0,然后对于 query 的每个值,增加哈希映射的值,并将键设置为 query。只需要遍历哈希映射以获得最终数组。哈希映射访问在(摊销的)常数时间内完成。不幸的是,Python dict 不支持数组作为键,因为数组不能被散列,但元组可以。这是一个例子:

counts = {tuple(row):0 for row in reference}

for row in query:
    key = tuple(row)
    if key in counts:
        counts[key] += 1

print(list(counts.values()))

这导致打印:[3, 3, 0, 1]

请注意,哈希映射中的顺序通常不守恒,但 Python dict 应该没问题。或者,可以使用另一个哈希映射来重建最终数组。

生成的解决方案对于小数组可能会更慢,但对于大数组应该更好。