Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找两个数组之间分组项匹配的索引_Python_Numpy - Fatal编程技术网

Python 查找两个数组之间分组项匹配的索引

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

我有两个整数列表,每个整数按每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,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])