在熊猫中的GroupBy对象内过滤

时间:2018-12-19 07:52:37

标签: 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

对于每个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

我想对每个组应用条件以获取以下信息:

1    ID  value
2     1    250
2    ID  value
4     2    130
5     2    108
3    ID  value
6     3    107

我尝试使用groupby.filter,但是会为整个组输出布尔条件。我想在一个组内应用一个布尔条件。我该怎么办?

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

3 个答案:

答案 0 :(得分:4)

您可以在循环之前或循环中通过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

如果某些组没有匹配的值,则像组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

或者,如果循环中的过滤器返回了不匹配组的空DataFrame:

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: []

编辑:

如果可能需要用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

详细信息

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

答案 1 :(得分:0)

除了用这种方式查询熊猫,我们还可以做得更好。.

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]})
df3 = df.query('value > 100')
print(df3.head())

输出将为

   ID  value
2   1    250
4   2    130
5   2    108
6   3    107

答案 2 :(得分:0)

您可以应用功能

def f(df, n):
    return df[df['value'] > n]

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

res = df.groupby('ID').apply(lambda x: f(x, 100))