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.transform
和 eq.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
我想保留满足条件的组的所有行至少一次。换句话说,我想至少删除一次不符合条件的组。
我已经四处寻找了几个小时,但找不到解决方案。
我有以下数据框:
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.transform
和 eq.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