Python 比较数组,找到相同的元素并返回索引

Python 比较数组,找到相同的元素并返回索引,python,numpy,Python,Numpy,我有两个numpy数组(长度不同) 第一个类似于(n): 第二个类似于(n,3): 现在我想检查第二个数组的每一列是否包含第一个数组中的一个数字,如果可能的话,返回该列的索引 b[0] -> [0, 1, 3] contains 0 and 1 so I need that index (only once) b[1] -> [8, 3, 9] does not contain any of the numbers from a, so I don't need that index

我有两个numpy数组(长度不同)

第一个类似于(n):

第二个类似于(n,3):

现在我想检查第二个数组的每一列是否包含第一个数组中的一个数字,如果可能的话,返回该列的索引

b[0] -> [0, 1, 3] contains 0 and 1 so I need that index (only once)
b[1] -> [8, 3, 9] does not contain any of the numbers from a, so I don't need that index
结果shell是一个包含所有这些索引的数组,在本例中如下所示:

indexes = [0, 3, 4, 5....]
有办法检查吗?处理速度不是问题

您可以使用获取匹配项的掩码。现在,
np.inad
在处理之前将输入平坦化。因此,我们需要在之后将其重塑为
2D
,然后检查每一行中是否存在任何一个匹配项,并获得具有这些匹配项的行索引

因此,执行工作将是非常重要的-

np.flatnonzero(np.in1d(b,a).reshape(b.shape).any(1))
给定样本的中间和最终输出的样本运行-

In [143]: a
Out[143]: array([0, 1, 2, 5, 6, 7])

In [144]: b
Out[144]: 
array([[0, 1, 3],
       [8, 3, 9],
       [9, 8, 4],
       [0, 4, 5],
       [1, 7, 3],
       [1, 5, 7],
       [2, 3, 7],
       [4, 2, 6],
       [5, 4, 6],
       [5, 6, 7]])

In [145]: np.in1d(b,a).reshape(b.shape)
Out[145]: 
array([[ True,  True, False],
       [False, False, False],
       [False, False, False],
       [ True, False,  True],
       [ True,  True, False],
       [ True,  True,  True],
       [ True, False,  True],
       [False,  True,  True],
       [ True, False,  True],
       [ True,  True,  True]], dtype=bool)

In [146]: np.in1d(b,a).reshape(b.shape).any(1)
Out[146]: array([ True, False, False,  True,  True, 
                    True,  True,  True,  True,  True], dtype=bool)

In [147]: np.flatnonzero(np.in1d(b,a).reshape(b.shape).any(1))
Out[147]: array([0, 3, 4, 5, 6, 7, 8, 9])
在D中使用

a = [0, 1, 2, 5, 6, 7]
b = [[0, 1, 3],[8, 3, 9],[9, 8, 4],[0, 4, 5],[1, 7, 3],[1, 5, 7],[2, 3, 7],[4, 2, 6],[5, 4, 6],[5, 6, 7]]
a, b = map(np.array, (a, b))
np.where(np.in1d(b, a).reshape(b.shape).any(axis=1))[0]

列表b应理解为一个矩阵,其中子列表是行,而不是列

话虽如此,考虑到您提供的示例,我假设您实际想要做的是在b行中查找匹配项。然后,我们将进行如下工作:

  • 检查a中的任何数字是否与b的给定子列表中包含的数字匹配

  • 获取一个数组,其元素是标识b的子列表的索引,这些子列表至少有一个a的数字

  • 我将使用标准的Python3 sintax,使用一个列表。然后,我将使用numpy asarray函数将其转换为数组:

    import numpy as np
    def matches(a,b):
    list = [] 
    for i in range(len(b)):
        for j in range(len(b[0])):
            if b[i][j] in a:
                list = list+[i]
                break
            else:
                 pass
    arrayIndexes = np.asarray(list)
    return arrayIndexes
    
    print(matches([0,1,2,5,6,7],
             [[0,1,3],
              [8,3,9],
              [9,8,4],
              [0,4,5],
              [1,7,3],
              [1,5,7],
              [2,3,7],
              [4,2,6],
              [5,4,6],
              [5,6,7]]))
    
    带有索引的返回numpy数组将是名为ArrayIndex的对象,并将包含以下内容:

    array([0,3,4,5,6,7,8,9])
    
    通过简单(但可能较大)的广播比较:

    In [14]: mask=a==b[:,:,None]
    In [15]: mask.shape
    Out[15]: (10, 3, 6)
    In [16]: mask.any(axis=2)    # any match over elements of a
    Out[16]: 
    array([[ True,  True, False],
           [False, False, False],
           [False, False, False],
           [ True, False,  True],
           [ True,  True, False],
           [ True,  True,  True],
           [ True, False,  True],
           [False,  True,  True],
           [ True, False,  True],
           [ True,  True,  True]], dtype=bool)
    In [17]: mask.any(axis=2).any(axis=1)   # and match on any colum
    Out[17]: array([ True, False, False,  True,  True,  True,  True,  True,  True,  True], dtype=bool)
    In [18]: np.where(mask.any(axis=2).any(axis=1))
    Out[18]: (array([0, 3, 4, 5, 6, 7, 8, 9], dtype=int32),)
    
    InAD有几种模式,这取决于两个输入的相对大小,但我认为其中一种是等效的

    In [26]: timeit np.where(np.any(a==b[:,:,None], axis=(1,2)))[0]
    The slowest run took 4.19 times longer than the fastest. This could mean that an intermediate result is being cached.
    100000 loops, best of 3: 18.3 µs per loop
    In [27]: timeit np.flatnonzero(np.in1d(b,a).reshape(b.shape).any(1))
    10000 loops, best of 3: 38.2 µs per loop
    

    您只需使用
    列表理解
    并使用
    any()
    即可完成此操作,如以下示例所示:

    a = [0, 1, 2, 5, 6, 7]
    b = [[0, 1, 3],[8, 3, 9],[9, 8, 4],[0, 4, 5],[1, 7, 3],[1, 5, 7],[2, 3, 7],[4, 2, 6],[5, 4, 6],[5, 6, 7]]
    
    final = [k for k in range(len(b)) if any(j in b[k] for j in a)]
    print(final)
    
    输出:

    [0, 3, 4, 5, 6, 7, 8, 9]
    

    在输出的
    索引中如何有
    2
    ?看起来像是打字错误,必须是
    3
    。对不起,你是对的!-我将尝试使用
    np对其进行编辑,这与另一篇文章中使用的
    np基本上不一样。因为
    flatnonzero
    只在
    1D
    np上工作。其中
    只获取
    索引,所以我们在那里得到第一个输出:)OP已经将输入作为数组。看来,我们也不需要这些映射。
    a = [0, 1, 2, 5, 6, 7]
    b = [[0, 1, 3],[8, 3, 9],[9, 8, 4],[0, 4, 5],[1, 7, 3],[1, 5, 7],[2, 3, 7],[4, 2, 6],[5, 4, 6],[5, 6, 7]]
    
    final = [k for k in range(len(b)) if any(j in b[k] for j in a)]
    print(final)
    
    [0, 3, 4, 5, 6, 7, 8, 9]