【问题标题】:How to delete values from one pandas series that are common to another?如何从一个熊猫系列中删除另一个共有的值?
【发布时间】:2021-12-14 20:10:24
【问题描述】:

所以我有一个需要解决的具体问题。我需要删除一个熊猫系列 (ser1) 中存在的元素,这些元素与另一个熊猫系列 (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

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

【问题讨论】:

  • Series.isin()

标签: python pandas indexing series drop


【解决方案1】:

使用.isin:

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

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

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

【讨论】:

    【解决方案2】:

    一个 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)
    

    【讨论】:

    • 我觉得你也应该把python的集合放在这里
    • @sammywemmy 不确定如何在这里使用 set,您的意思是转换为 set 并返回系列?
    • set(ser1).difference(ser2) ... set 的危险在于它是无序的
    • 工作,感谢您的宝贵时间!
    • @sammywemmy Set 确实很快,但没有订购。对于相同的值,它给出 29us
    【解决方案3】:

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

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

    【讨论】:

    • 这很好,谢谢,为什么新系列的索引不是从 0 开始有什么原因吗?
    • ahhh ...所以索引被重复,既作为索引,又作为系列。在to_series 方法中,您可以手动传入新索引。或者只是 reset_index
    • 重置我使用的索引:ser1 = (pd.Index(ser1).difference(ser2).to_series()) ser1 = ser1.reset_index() print(ser1) 它给了我这个答案:Name: alphabets, dtype: object index 0 0 1 1 1 2 2 2 3 3
    • 使用reset_index(drop=True)
    • 工作,谢谢你的回答,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2016-09-15
    • 2021-12-14
    • 1970-01-01
    • 2022-07-13
    相关资源
    最近更新 更多