有效匹配2d数组

时间:2016-07-19 21:27:53

标签: python arrays python-2.7 numpy

我有一个2d坐标数组,我想找到与给定坐标匹配的条目索引。

例如,我的数组可以是A

A = [[[1.5, 2.0], [1.0, 2.3], [5.4, 2.3]],
     [[3.2, 4.4], [2.0, 3.1], [0.0, 2.3]],
     [[1.0, 2.0], [2.3, 3.4], [4.0, 1.1]]]

我要匹配的坐标是x = [1.0, 2.0]。我想得到坐标[1.0, 2.0]的索引,它将是(2, 0)

目前我的工作如下:

matching_inds = [(i, j) for i in xrange(len(A)) for j in xrange(len(A[0])) if A[i,j][0] == x[0] and A[i,j][1] == x[1]]

这很有效,但我觉得应该有更高效的东西(我正在使用的数组要大得多)。

我尝试了np.where(),但是对于更高的维度,这似乎并不太好。它将返回x坐标匹配的所有坐标的索引,而不是x和y坐标。

任何提示都将不胜感激。

3 个答案:

答案 0 :(得分:2)

您可以使用稍微简单的代码版本:

In [115]: A = [[[1.5, 2.0], [1.0, 2.3], [5.4, 2.3]],
     ...:      [[3.2, 4.4], [2.0, 3.1], [0.0, 2.3]],
     ...:      [[1.0, 2.0], [2.3, 3.4], [4.0, 1.1]]]

In [116]: x = [1., 2.]

In [117]: [(i, j) for i, row in enumerate(A) for j, coor in enumerate(row) if coor == x]
Out[117]: [(2, 0)]

但是如果数组很大,你最好使用矢量化方法:

In [118]: import numpy as np

In [119]: arr = np.array(A)

In [120]: np.argwhere(np.logical_and(arr[:,:,0] == x[0], arr[:,:,1] == x[1]))
Out[120]: array([[2, 0]], dtype=int64)

编辑:完成工作的有效而优雅的方法是:

In [158]: np.argwhere(np.all(arr == x, axis=2))
Out[158]: array([[2, 0]], dtype=int64)

答案 1 :(得分:1)

你可以试试这个:

import numpy as np
arrA = np.array(A)
x = [1.0, 2.0]

np.where((arrA == x).sum(axis = 2) == 2)
# (array([2]), array([0]))

答案 2 :(得分:1)

如果您要进行大量查找,可以构建一个索引,将坐标映射到矩阵中的位置。例如,(1.5, 2.0)映射到(0,0)(1.0, 2.3)映射到(0, 1),等等。以下是如何构建数组的索引:

>>> A = [[[1.5,  2.0],[1.0,  2.3],[5.4,  2.3]],
...     [[3.2,  4.4],[2.0,  3.1],[0.0,  2.3]],
...     [[1.0,  2.0],[2.3,  3.4],[4.0,  1.1]]]
>>> revind = dict()
>>> for r, row in enumerate(A):
...     for c, pt in enumerate(row):
...         revind[tuple(pt)] = (r, c)
... 
>>> revind[(1.0, 2.0)]
(2,0)

或作为(不太可读)理解:

>>> revind = dict((tuple(pt), (r,c)) for r,row in enumerate(A) for c,pt in enumerate(row))

请注意,您必须使用元组,因为列表是“可变的”,不能用作字典键。这样做可以确保每次查找都在O(1)时间内完成,这比搜索长列表要快得多(如在您的问题和接受的答案中)。