如何从一个 pandas 系列中删除另一个系列共有的值?

How to delete values from one pandas series that are common to another?

所以我有一个具体的问题需要解决。我需要删除一个 pandas 系列 (ser1) 中存在的元素,这些元素与另一个 pandas 系列 (ser2) 共有。

我已经尝试了一堆不起作用的东西,我能找到的最接近的东西是使用 np.intersect1d() 函数的数组。这可以找到共同的值,但是当我尝试删除等于这些值的索引时,我会犯很多错误。

我已经尝试了很多其他的东西,但都没有真正起作用,并且已经尝试了 3 个小时,所以快要放弃了。

这是两个系列:

ser1 = pd.Series([1, 2, 3, 4, 5])
ser2 = pd.Series([4, 5, 6, 7, 8])

结果应该是:

print(ser1)
0   1
1   2
2   3

我相信有一个简单的解决方案。

使用.isin:

>>> ser1[~ser1.isin(ser2)]
0    1
1    2
2    3
dtype: int64

numpy 版本是 .setdiff1d(而不是 .intersect1d

>>> np.setdiff1d(ser1, ser2)
array([1, 2, 3])

您可以使用集合表示法 - 不过与 isin 相比,我不确定速度:

pd.Index(ser1).difference(ser2).to_series()
Out[35]: 
1    1
2    2
3    3
dtype: int64

一个 numpy 的替代品,np.isin

import pandas as pd
import numpy as np

ser1 = pd.Series([1, 2, 3, 4, 5])
ser2 = pd.Series([4, 5, 6, 7, 8])

res = ser1[~np.isin(ser1, ser2)]
print(res)

微基准测试

import pandas as pd
import numpy as np
ser1 = pd.Series([1, 2, 3, 4, 5] * 100)
ser2 = pd.Series([4, 5, 6, 7, 8] * 10)
%timeit res = ser1[~np.isin(ser1, ser2)]
136 µs ± 2.56 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit res = ser1[~ser1.isin(ser2)]
209 µs ± 1.66 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit pd.Index(ser1).difference(ser2).to_series()
277 µs ± 1.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)