Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从一个数组中删除元素(如果存在于另一个数组中),保留重复项-NumPy/Python_Python_Numpy_For Loop_Unique - Fatal编程技术网

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

从一个数组中删除元素(如果存在于另一个数组中),保留重复项-NumPy/Python,python,numpy,for-loop,unique,Python,Numpy,For Loop,Unique,我有两个阵列A(len为380万)和B(len为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循环的情况下执行该操作,因为它是一个很长的数组,因此循环需要很长时间 使用sear

我有两个阵列
A
(len为380万)和
B
(len为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,v)
将索引查找到排序数组
a
,这样,如果在索引之前插入
v
中的相应元素,则a的顺序将被保留。因此,我们假设
idx=searchsorted(B,A)
,我们将索引到
B
,通过这些:
B[idx]
,我们将得到
B
的映射版本,对应于
A
中的每个元素。因此,将此映射版本与
A
进行比较,可以告诉我们
A
中的每个元素是否与
B
匹配。最后,索引到
A
以选择不匹配的

一般情况(
B
未排序):

sidx = B.argsort()
idx = np.searchsorted(B,A,sorter=sidx)
idx[idx==len(B)] = 0
out = A[B[sidx[idx]] != A]
如果
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]

在AD/isin中使用

我们还可以使用,这是非常直接的(链接文档应该有助于澄清),因为它在
B
中为
A
中的每个元素查找任何匹配项,然后我们可以使用带反转掩码的布尔索引来查找不匹配项-

A[~np.in1d(A,B)]
与isin相同-

A[~np.isin(A,B)]
使用
反转
标志-

A[np.in1d(A,B,invert=True)]

A[np.isin(A,B,invert=True)]

这就解决了当
B
不一定排序时的泛型问题。

我对numpy不是很熟悉,但是如何使用集合:

C = set(A.flat) - set(B.flat)
编辑:从注释中,集合不能有重复的值

因此,另一种解决方案是使用lambda表达式:

C = np.array(list(filter(lambda x: x not in B, A)))
加上-

如果原始数组A的范围比B大,则会出现“索引超出范围”错误。见:

A = np.array([1,1,2,3,3,3,4,5,6,7,8,8,10,12,14])
B = np.array([1,2,8])

A[B[np.searchsorted(B,A)] !=  A]
>> IndexError: index 3 is out of bounds for axis 0 with size 3

这是因为
np。在本例中,searchsorted
将索引3(B中最后一个之后的一个)指定为在B中插入A中的元素10、12和14的适当位置。因此,在
B[np.searchsorted(B,A)]
中会得到一个索引器

为了避免这种情况,一种可能的方法是:

def subset_sorted_array(A,B):
    Aa = A[np.where(A <= np.max(B))]
    Bb = (B[np.searchsorted(B,Aa)] !=  Aa)
    Bb = np.pad(Bb,(0,A.shape[0]-Aa.shape[0]), method='constant', constant_values=True)
    return A[Bb]
def子集排序数组(A,B):
Aa=A[np.式中(数组([3,3,3,4,5,6,7,10,12,14]))

请注意,这也适用于字符串数组和其他类型(对于比较
.B
已排序的所有类型?@Divakar:no,但如果需要,我可以对其进行排序,这不是问题。setdiff1d
不会做您需要的事情吗?我可以获得有关这两种方法如何工作的更多信息吗?使用
timeit
,似乎第一种方法大约需要两次faster@ThePredator加d注释。这是一个很好且切中要害的答案,但如果a中的值的范围大于B中的值(即,如果a中有较大的值而B中没有),则这不会直接起作用.我将为将来添加一个补充答案reference@vmg说得好!已编辑的解决方案也可以处理这些情况。集合不能包含重复的值。Awesiome。您保存了我的夜晚
# Take only the elements in A that would be inserted in B
Aa = A[np.where(A <= np.max(B))]

# Pad the resulting filter with 'Trues' - I split this in two operations for
# easier reading
Bb = (B[np.searchsorted(B,Aa)] !=  Aa)
Bb = np.pad(Bb,(0,A.shape[0]-Aa.shape[0]),  method='constant', constant_values=True)

# Then you can filter A by Bb
A[Bb]
# For the input arrays above:
>> array([ 3,  3,  3,  4,  5,  6,  7, 10, 12, 14])