Python 查找两个数组之间分组项匹配的索引
我有两个整数列表,每个整数按每2个连续项分组(即索引[0,1],[2,3]等等)。 在两个列表中都找不到重复的项对,无论是相同顺序还是相反顺序 一个列表要大得多,并且包含了另一个列表。 我正试图找出一种有效的方法来获取指数 较大列表的分组项中,也位于较小列表中的项 上述示例中的期望输出应为:Python 查找两个数组之间分组项匹配的索引,python,numpy,Python,Numpy,我有两个整数列表,每个整数按每2个连续项分组(即索引[0,1],[2,3]等等)。 在两个列表中都找不到重复的项对,无论是相同顺序还是相反顺序 一个列表要大得多,并且包含了另一个列表。 我正试图找出一种有效的方法来获取指数 较大列表的分组项中,也位于较小列表中的项 上述示例中的期望输出应为: a = np.array([5,8,3,4,2,5,7,8,1,9,1,3,4,7]) b = np.array ([3,4,7,8,1,3]) 请注意,作为一个示例,第一组([3,4])不应获得索引11
a = np.array([5,8,3,4,2,5,7,8,1,9,1,3,4,7])
b = np.array ([3,4,7,8,1,3])
请注意,作为一个示例,第一组([3,4])不应获得索引11,12作为匹配项,因为在这种情况下,3是[1,3]的第二个元素,4是[4,7]的第一个元素。这里有一种方法使用元素组的
NumPy view
-
[2,3,6,7,10,11] #indices
如果a
中b
的任何组之间没有成员资格,我们可以使用掩码将其过滤掉:a0v[idx]==b0v
样本运行-
# Taken from https://stackoverflow.com/a/45313353/
def view1D(a, b): # a, b are arrays
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel(), b.view(void_dt).ravel()
def grouped_indices(a, b):
a0v, b0v = view1D(a.reshape(-1,2), b.reshape(-1,2))
sidx = a0v.argsort()
idx = sidx[np.searchsorted(a0v,b0v, sorter=sidx)]
return ((idx*2)[:,None] + [0,1]).ravel()
另一个使用
np.inad
替换np.searchsorted
-
In [345]: a
Out[345]: array([5, 8, 3, 4, 2, 5, 7, 8, 1, 9, 1, 3, 4, 7])
In [346]: b
Out[346]: array([3, 4, 7, 8, 1, 3])
In [347]: grouped_indices(a, b)
Out[347]: array([ 2, 3, 6, 7, 10, 11])
由于您是按对对数组进行分组,因此可以将它们重新调整为两列进行比较。然后可以将较短数组中的每个元素与较长数组中的每个元素进行比较,并减少布尔数组。从这里开始,使用经过整形的
np.arange
获得索引是一件简单的事情
def grouped_indices_v2(a, b):
a0v, b0v = view1D(a.reshape(-1,2), b.reshape(-1,2))
return (np.flatnonzero(np.in1d(a0v, b0v))[:,None]*2 + [0,1]).ravel()
如果你想要一个平面阵列,只需拉威尔ix
import numpy as np
from functools import reduce
a = np.array([5,8,3,4,2,5,7,8,1,9,1,3,4,7])
b = np.array ([3,4,7,8,1,3])
# reshape a and b into columns
a2 = a.reshape((-1,2))
b2 = b.reshape((-1,2))
# create a generator of bools for the row of a2 that holds b2
b_in_a_generator = (np.all(a2==row, axis=1) for row in b2)
# reduce the generator to get an array of boolean that is True for each row
# of a2 that equals one of the rows of b2
ix_bool = reduce(lambda x,y: x+y, b_in_a_generator)
# grab the indices by slicing a reshaped np.arange array
ix = np.arange(len(a)).reshape((-1,2))[ix_bool]
ix
# returns:
array([[ 2, 3],
[ 6, 7],
[10, 11]])
谢谢你,回答得很好。我选择@Divakar作为被接受的一个,只是因为
reduce(lambda…
对于真正大的设置需要相当长的时间。再次感谢您的回答。您是否猜到了为什么in1d
中的可能无法正常工作,而searchsorted
与我已经检查过的实际集合一起工作:b
的所有元素都包含在a
中;成对元素在a
和b
中是唯一的条目,这可能是因为b
中的分组顺序与a
中的顺序不同。这就像是b
是数组([1,3,3,4,7,8,])
而不是数组([3,4,7,8,1,3])
。
ix.ravel()
# returns
array([ 2, 3, 6, 7, 10, 11])