我有两个数组 A
(380 万的长度)和 B
(20k 的长度)。
对于最小的示例,让我们以这种情况为例:
A = np.array([1,1,2,3,3,3,4,5,6,7,8,8])
B = np.array([1,2,8])
现在我希望得到的数组是:
C = np.array([3,3,3,4,5,6,7])
即如果在 A
中找到 B
中的任何值,则将其从 A
中删除,如果不保留它。
我想知道是否有没有for
循环 的方法,因为它是一个很长的数组,因此循环需要很长时间。
最佳答案
使用searchsorted
有了排序的B
,我们可以使用searchsorted
-
A[B[np.searchsorted(B,A)] != A]
从链接文档中,searchsorted(a,v)
找到排序数组 a
中的索引,如果 v
中的相应元素code> 被插入到索引之前,a 的顺序将被保留。所以,假设 idx = searchsorted(B,A)
并且我们用这些索引到 B
:B[idx]
,我们将得到一个B
的映射版本对应于 A
中的每个元素。因此,将此映射版本与 A
进行比较会告诉我们 A
中的每个元素是否在 B
中存在匹配项。最后,索引到 A
以选择不匹配的。
一般情况(B
未排序):
如果 B
尚未按照先决条件进行排序,请对其进行排序,然后使用建议的方法。
或者,我们可以使用 sorter
参数和 searchsorted
-
sidx = B.argsort()
out = A[B[sidx[np.searchsorted(B,A,sorter=sidx)]] != A]
更通用的情况(A
的值高于 B
中的值):
sidx = B.argsort()
idx = np.searchsorted(B,A,sorter=sidx)
idx[idx==len(B)] = 0
out = A[B[sidx[idx]] != A]
使用in1d/isin
我们也可以使用np.in1d
,这是非常简单的(链接文档应该有助于澄清),因为它为 A
中的每个元素查找 B
中的任何匹配项,然后我们可以使用 bool 索引用倒置的掩码来寻找不匹配的 -
A[~np.in1d(A,B)]
与 isin
相同 -
A[~np.isin(A,B)]
带有 invert
标志 -
A[np.in1d(A,B,invert=True)]
A[np.isin(A,B,invert=True)]
当 B
不一定排序时,这解决了泛型问题。
关于python - 如果存在于另一个数组中,则从一个数组中删除元素,保留重复元素 - NumPy/Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52417929/