【问题标题】:Keep rows of dataframe if multiple conditions met如果满足多个条件,则保留数据框行
【发布时间】:2020-11-14 21:11:19
【问题描述】:

给定以下数据框:

df = pd.DataFrame({'A': ["EQ", "CB", "CB", "FF", "EQ", "EQ", "CB", "CB"],
                   'B': ["ANT", "ANT", "DQ", "DQ", "BQ", "VGQ", "GHB", "VGQ"]})

如果满足exist for both EQ and CB 的条件,如何保留B 列的行。例如,我想保留ANT,因为它同时存在于EQCB,而DQ 将被删除。所以df 的预期输出是:

out = pd.DataFrame({'A': ["EQ", "CB", "EQ", "CB"],
                       'B': ["ANT", "ANT", "VGQ", "VGQ"]})

谢谢!

【问题讨论】:

    标签: pandas dataframe conditional-statements sample


    【解决方案1】:

    另一种方式使用transform 和切片

    m = df.groupby('B').A.transform(lambda x: (x.nunique() >= 2) 
                                            & (x.isin(['EQ', 'CB']).sum() >= 2))
    df_final = df[m]
    
    Out[623]:
        A    B
    0  EQ  ANT
    1  CB  ANT
    5  EQ  VGQ
    7  CB  VGQ
    

    【讨论】:

    • 如果每组有两个相同的 EQ ~
    • @YOBEN_S:是的,我想到了nunique。你的鼓励真的促使我修复它:)
    【解决方案2】:

    如果您想要更容易思考的代码,这里有一个不使用 groupby() 的解决方案:

    equities = df.B[df.A == 'EQ']
    bonds = df.B[df.A == 'CB']
    both = equities[equities.isin(bonds)]
    

    这给了你:

    0    ANT
    5    VGQ
    

    这使得最后一部分变得简单:

    df[df.B.isin(both)]
    Out: 
        A    B
    0  EQ  ANT
    1  CB  ANT
    5  EQ  VGQ
    7  CB  VGQ
    

    这在小型数据集上比 groupby().filter() 快 3 倍。

    【讨论】:

    • 感谢我弄清楚我实际使用的是什么 - 股票和债券 :)。会检查的!
    • @AK88:我使用您的小输入样本进行了测试,这比 groupby().filter() 快 3 倍。你能用你的真实数据测试两者并让我们知道速度吗?如果您使用 IPython,只需将每个解决方案放入一个函数并使用 %timeit 运行即可。
    • 现在测试它。很快就会回复你。我喜欢这种方法直观而简单的步骤。
    • 有其他列会影响这个吗?我不知道为什么我会在输出中看到除 EQ 和 CB 之外的其他内容...
    • @AK88:你最初的问题听起来像是你想看到所有有 EQ 和 CB 的东西,而不是你也想看不到非 EQ,非-CB 行。只需将equities_and_bonds = df[df.A.isin(['EQ', 'CB'])] 作为第一步,然后将该 DataFrame 用于其余步骤。或者在最后做同样的过滤。其他列不影响这一点。
    【解决方案3】:

    让我们试试filter

    s=df.groupby('B').filter(lambda x : pd.Series(['EQ','CB']).isin(x['A']).all())
    Out[7]: 
        A    B
    0  EQ  ANT
    1  CB  ANT
    5  EQ  VGQ
    7  CB  VGQ
    

    然后

    s=s[s.A.isin(['EQ','CB'])]
    

    【讨论】:

    • 这个过滤器应该去掉A下的其他类别,对吧?我只是用我的原始数据集运行了这个,但我没有看到 EQCB。原始数据集要大得多,有 EQCB 的重复项。
    • 我觉得所有的副本都被砸在一起了。另外,我看到了部分数据。正在调查...
    • 超过 2 列会是个问题吗?我不知道为什么我一直看到其他类别以及EQCB
    • @AK88 这个解决方案是基于你的样本数据和预期的输出,你应该检查你的原始数据和样本并告诉我们不同,然后让问题解决你真正的数据集问题
    • @AK88 也别忘了在 groupby 之后运行s=s[s.A.isin(['EQ','CB'])]
    猜你喜欢
    • 2021-10-15
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多