python - 如果存在于另一个数组中,则从一个数组中删除元素,保留重复元素 - NumPy/Python

标签 python numpy for-loop unique

我有两个数组 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/

相关文章:

python - 非比例随机样本

python - 使用两个数组的最小值创建矩阵

python - Networkx Python 中的权重相乘

python - 用 Python 复制 SAS 的第一个和最后一个功能

没有填充的python卷积

java - 使用 for 循环打印到 java GUI

swift - 在 Swift 中访问结构数组的索引#

javascript - cakephp javascript动态更新

python - 为什么 Python 的 string.printable 包含不可打印的字符?

python - 将 Flask 项目部署到 Heroku 时出现 "Install dependencies with pip"异常