4

我想保留至少一次满足条件的组的所有行。换句话说,我想将不满足条件的组至少丢弃一次。

我已经四处寻找了几个小时,但找不到解决方案。这是我得到的最接近的结果,但我无法实现答案。

我有以下数据框:

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"]并选择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

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

我试过这个:

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

6 回答 6

3

容易理解filter

test.groupby('Gr').filter(lambda x : x['Bk'].eq(9).any())
   Gr  Bk
0   1   9
1   1   1
于 2019-08-19T00:48:30.307 回答
2

使用GroupBy.transformwitheq.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
于 2019-08-18T23:49:39.223 回答
2

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

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

结果

    Gr  Bk
0   1   9
1   1   1
于 2019-08-19T00:12:07.810 回答
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
于 2019-08-18T23:55:25.900 回答
1

这里非常简单的方法..

检查 test['Bk'] 等于 9 的位置,并获取 test['Gr'] 中的相应值,然后将 df 减少到仅出现这些 test['Gr'] 值的行

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

结果 :

   Gr  Bk
0   1   9
1   1   1
于 2019-08-19T02:03:49.810 回答
0

Bk=9假设每组只有一个Gr。这是使用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,但我认为在这一点上它变得太复杂并且不再有趣了

于 2019-08-19T01:12:44.277 回答