numpy数组中值数组的位置

时间:2013-07-22 20:38:28

标签: python numpy

这是一个用于说明问题的小代码。

A = array([[1,2], [1,0], [5,3]])
f_of_A = f(A)   # this is precomputed and expensive


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


# location of values in A
# if I just had 1d values I could use numpy.in1d here
indices = array([0, 1])


# example of operation type I need (recalculating f_of_A as needed is not an option)
f_of_A[ indices ]

所以,基本上我认为我需要一些相当于in1d的更高维度。这样的事情存在吗?还是有其他方法吗?

看起来还有一个searchsorted()函数,但这似乎也适用于1d数组。在这个例子中,我使用了2d点,但任何解决方案都需要为3d点工作。

2 个答案:

答案 0 :(得分:2)

好的,这就是我想出来的。

要查找一个多维索引的值,让我们说ii = np.array([1,2]),我们可以这样做:

n.where((A == ii).all(axis=1))[0]

让我们分解一下,我们有A == ii,它会为ii的每一行提供与A的元素比较。我们希望整行都是真的,因此我们添加.all(axis=1)来折叠它们。为了找到这些索引发生的位置,我们将其插入np.where并获取元组的第一个值。

现在,我还没有快速的方法来实现多指数(尽管我有一种感觉)。但是,这将完成工作:

np.hstack([np.where((A == values[i]).all(axis=1))[0] for i in xrange(len(values))])

这基本上只针对values的每个值调用上面的内容,并连接结果。

<强>更新

这是针对多维案例(一次性完成,应该相当快):

np.where((np.expand_dims(A, -1) == values.T).all(axis=1).any(axis=1))[0]

答案 1 :(得分:1)

您可以在原始数组的视图上使用np.in1d,并将所有坐标折叠为dtype np.void的单个变量:

import numpy as np

A = np.array([[1,2], [1,0], [5,3]])
values = np.array([[1,2], [1,0]])

# Make sure both arrays are contiguous and have common dtype
common_dtype = np.common_type(A, values)
a = np.ascontiguousarray(A, dtype=common_dtype)
vals = np.ascontiguousarray(values, dtype=common_dtype)

a_view = A.view((np.void, A.dtype.itemsize*A.shape[1])).ravel()
values_view = values.view((np.void,
                           values.dtype.itemsize*values.shape[1])).ravel()

现在a_viewvalues_view的每个项目都是一个点组合在一起的所有坐标,所以你可以做任何你会使用的1D魔法。我不知道如何使用np.in1d来查找索引,所以我会去np.searchsorted路线:

sort_idx = np.argsort(a_view)
locations = np.searchsorted(a_view, values_view, sorter=sort_idx)
locations = sort_idx[locations]

>>> locations
array([0, 1], dtype=int64)