如果满足多个条件,则保留数据框行

Keep rows of dataframe if multiple conditions met

给定以下数据框:

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

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

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

谢谢!

让我们试试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'])]

另一种方式使用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

如果您想要更容易思考的代码,这里有一个不使用 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 倍。