在 Pandas 中的 GroupBy 对象中过滤

ber*_*lem 2 python pandas pandas-groupby

这是一个示例数据框:

import pandas as pd
df = pd.DataFrame({'ID':[1,1,1,2,2,2,3,3], 
                   'value':[42, 89, 250, 31, 130, 108, 107, 93]})

    ID  value
0    1     42
1    1     89
2    1    250
3    2     31
4    2    130
5    2    108
6    3    107
7    3     93
Run Code Online (Sandbox Code Playgroud)

对于每个 ID,我想提取值大于 100 的条目。

使用groupby我可以获得以下内容

grouped = df.groupby('ID')
for name, group in grouped:
    print(name, group)

1    ID  value
0     1     42
1     1     89
2     1    250
2    ID  value
3     2     31
4     2    130
5     2    108
3    ID  value
6     3    107
7     3     93
Run Code Online (Sandbox Code Playgroud)

我想对每个组应用一个条件以获得以下结果:

1    ID  value
2     1    250
2    ID  value
4     2    130
5     2    108
3    ID  value
6     3    107
Run Code Online (Sandbox Code Playgroud)

我试过使用,groupby.filter但它为整个组输出一个布尔条件。我想在组内应用布尔条件。我怎样才能做到这一点?

编辑:我应该指定每个组内的条件不同,所以我需要先做 groupby。

jez*_*ael 5

您可以boolean indexing在循环之前或循环中过滤:

df = pd.DataFrame({'ID':[1,1,1,2,2,2,3,3], 
                   'value':[42, 89, 250, 31, 130, 108, 10, 93]})

print (df)
   ID  value
0   1     42
1   1     89
2   1    250
3   2     31
4   2    130
5   2    108
6   3     10
7   3     93
Run Code Online (Sandbox Code Playgroud)

如果某些组没有匹配的值,则像 group 一样省略3

grouped = df[df['value'] > 100].groupby('ID')
for name, group in grouped:
    print(name, group)
1    ID  value
2   1    250
2    ID  value
4   2    130
5   2    108
Run Code Online (Sandbox Code Playgroud)

或者,如果循环中的过滤器为不匹配的组返回空数据帧:

grouped = df.groupby('ID')
for name, group in grouped:
    print(name, group[group['value'] > 100])

1    ID  value
2   1    250
2    ID  value
4   2    130
5   2    108
3 Empty DataFrame
Columns: [ID, value]
Index: []
Run Code Online (Sandbox Code Playgroud)

编辑:

如果想要按每个组不同的值过滤是可能的解决方案,map按字典与ID列,然后比较value和过滤boolean indexing

d = {1:100, 2: 121, 3: 10}

df = df[df['value'] > df['ID'].map(d)]
print (df)
   ID  value
2   1    250
4   2    130
7   3     93
Run Code Online (Sandbox Code Playgroud)

详情

print (df['ID'].map(d))
0    100
1    100
2    100
3    121
4    121
5    121
6     10
7     10
Name: ID, dtype: int64
Run Code Online (Sandbox Code Playgroud)