Фильтр внутри объектов GroupBy в Pandas - PullRequest
0 голосов
/ 19 декабря 2018

Вот пример кадра данных:

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

Для каждого идентификатора я хочу извлечь записи со значениями больше 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 голосов
/ 19 декабря 2018

Мы можем сделать больше, чем запросить этот способ в пандах.

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
0 голосов
/ 19 декабря 2018

Вы можете применить функцию:

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))
0 голосов
/ 19 декабря 2018

Вы можете отфильтровать по 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...