如何通过numpy数组b的元素过滤numpy数组a,从而获得a中不在b中的所有点.
import numpy as np
a = np.array([[1,2],[1,3],[1,4]])
b = np.array([[1,2],[1,3]])
c = np.array([ d for d in a if d not in b])
print(c)
# acutall outcome
# []
# desired outcome
# np.array([[1,4]])```
如何通过numpy数组b的元素过滤numpy数组a,从而获得a中不在b中的所有点.
import numpy as np
a = np.array([[1,2],[1,3],[1,4]])
b = np.array([[1,2],[1,3]])
c = np.array([ d for d in a if d not in b])
print(c)
# acutall outcome
# []
# desired outcome
# np.array([[1,4]])```
这可能不是最有效的方法(尽管事实证明它比这里介绍的其他方法更快——见下文),但您可以做的一件事是将a
和b
转换为Python列表,然后取它们的集差:
# Method 1
tmp_1 = [tuple(i) for i in a] # -> [(1, 2), (1, 3), (1, 4)]
tmp_2 = [tuple(i) for i in b] # -> [(1, 2), (1, 3)]
c = np.array(list(set(tmp_1).difference(tmp_2)))
正如@EmiOB所指出的,this post提供了一些关于为什么你问题中的[ d for d in a if d not in b ]
不起作用的见解.从那篇文章中,你可以使用
# Method 2
c = np.array([d for d in a if all(any(d != i) for i in b)])
Remarks
array_contains(PyArrayObject *self, PyObject *el)
中的The implementation(C)表示拨打array_contains(self, el)
(C)相当于
(self == el).any()
在Python中,
换句话说:
arr
是一个numpy数组,obj
是一个任意的Python对象,那么obj in arr
和
(arr == obj).any()
arr
是一个典型的Python容器,比如列表、元组、字典等等,那么obj in arr
和
any(obj is _ or obj == _ for _ in arr)
(见membership test operations).
也就是说,obj in arr
的含义因arr
的类型而异.
这就解释了为什么你提出的逻辑理解没有达到预期的效果.
这可能会让人困惑,因为人们很容易推断,既然numpy数组是一个序列(虽然不是标准的Python数组),那么测试成员语义应该是相同的.事实并非如此.
例子:
a = np.array([[1,2],[1,3],[1,4]])
print((a == [1,2]).any()) # same as [1, 2] in a
# outputs True
Timings
对于您的输入,我发现我的方法是最快的,其次是从@EmiOB建议的帖子中获得的方法2,然后是@DanielF的方法.如果改变输入大小会改变计时的顺序,我也不会感到惊讶,所以请恕我直言.
# Method 1
5.96 µs ± 8.92 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
# Method 2
6.45 µs ± 27.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
# @DanielF's answer
16.5 µs ± 276 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)