在Python中确定两个NumPy数组相交的参数。

6

我有两个数组,如下:

a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])

我需要找出a中所有不在b中的元素的索引。 在上面的例子中,结果将会是:
[0, 1, 3]

因为a[0]、a[1]和a[3]的值分别为13、14和32,而这些值在b中不存在。请注意,我并不关心13、14和32的实际值(在这种情况下,我可以使用set(a).difference(set(b)))。我只对索引感兴趣。
如果可能的话,答案应该是“向量化”的,即不使用for循环。

在这个例子中,它们都是排序数组,这只是巧合吗?(如果它们在您的问题的真实版本中已经排序,您可以利用这个属性) - usethedeathstar
抱歉,我使用了排序数组来帮助阅读。但我仍然很想听听您对于排序数组的看法 :) - astabada
一个自定义算法可能会通过滥用它们已排序的事实来获得更好的复杂度(我不确定最终会得到什么复杂度,但我认为比如果没有这个属性做任何事情都要好)。 - usethedeathstar
3个回答

3
您可以使用np.in1d来实现:

np.in1d

>>> np.arange(a.shape[0])[~np.in1d(a,b)].tolist()
  [0, 1, 3]

2
很容易,使用 numpy.intersect1d 来计算 ab 之间的共享元素,然后使用 numpy.in1d 检查这些元素中哪些不在 a 中,并最终通过 numpy.argwhere 获取它们在数组中的位置。
>>> import numpy as np
>>> a, b = np.array([13., 14., 15., 32., 33.]), np.array([15., 16., 17., 33., 34., 47.])
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False)
array([[0],
   [1],
   [3]])

如果你想要一个列表,只需添加.flatten以将矩阵转换为向量,然后应用.tolist以获取列表:
>>> np.argwhere(np.in1d(a, np.intersect1d(a,b)) == False).flatten().tolist()
 [0, 1, 3]

1
相当简单,如果您使用循环的话:

def difference_indices(a, b):

    # Set to put the unique indices in
    indices = []

    # So we know the index of the element of a that we're looking at
    a_index = 0

    for elem_a in a:

        found_in_b = False
        b_index = 0

        # Loop until we find a match. If we reach the end of b without a match, the current 
        # a index should go in the indices list
        while not found_in_b and b_index < len(b):
            if elem_a == b[b_index]: found_in_b = True
            b_index = b_index + 1

        if not found_in_b: indices.append(a_index)
        a_index = a_index + 1

    return indices

只要列表中的类型相同,并且已为该类型定义了__eq__函数,它就可以与包含任何一种类型的列表一起使用。

如果不使用循环来完成这个任务,需要对Python有更深入的了解。希望这对您有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接