Select 所有满足条件至少一次的组

Select all the groups that meet condition at least once

我想保留满足条件的组的所有行至少一次。换句话说,我想至少删除一次不符合条件的组。

我已经四处寻找了几个小时,但找不到解决方案。 但我无法实现答案。

我有以下数据框:

test = pd.DataFrame({"Gr":[1,1,2,2],"Bk":[9,1,8,5]})
print(test)

   Gr  Bk
0   1   9
1   1   1
2   2   8
3   2   5

我想按 test["Gr"] 和 select 所有 test["Bk"] == 9 至少一次的组进行分组以达到此目的:

# Drop Gr 2 because they didn't meet Bk == 1 in any of its rows.
   Gr  Bk
0   1   9
1   1   1

我原以为这可以通过组合 groupby().any() 轻松实现,而不需要 lambda 函数。

我试过这个:

test.groupby("Gr").filter(lambda x: (x.Bk == 9).all())

使用 GroupBy.transformeq.any 检查每个组内的值是否 any 等于 (eq) 到 9:

mask = test.groupby('Gr')['Bk'].transform(lambda x: x.eq(9).any())
test[mask]

输出

   Gr  Bk
0   1   9
1   1   1

你可以这样做:

test =test[test['Gr'].apply(lambda x: x in [key for key in test['Gr'][test['Bk'].eq(9)]])]
test

输出:

    Gr  Bk
0   1   9
1   1   1

没有groupby也是有可能的。只需检查所有条目是否等于 9,获取此条目的组并为提取的组切片整个数据帧。

test[test.Gr.isin(test[test['Bk'].eq(9)].Gr)]

结果

    Gr  Bk
0   1   9
1   1   1

通俗易懂filter

test.groupby('Gr').filter(lambda x : x['Bk'].eq(9).any())
   Gr  Bk
0   1   9
1   1   1

假设每组 Gr 只有一个 Bk=9 。这是使用 merge 的一种疯狂且矫枉过正的方式:D

test.merge(test.loc[test.Bk.eq(9),'Gr'], on='Gr')

Out[227]:
   Gr  Bk
0  1   9
1  1   1

注意:它仍然适用于每组多个 9。它只需要 drop_duplicates,但我认为到那时它变得太复杂了,不再有趣了

这里的方法非常简单..

检查 test['Bk'] 等于 9 的位置,并在 test['Gr'] 中获取相应的值,然后将 df 减少到只有 test['Bk'] 的这些值所在的行'Gr']正在发生

test[test['Gr'].isin(test[test['Bk']==9]['Gr'])]

结果:

   Gr  Bk
0   1   9
1   1   1