Подмножество pandas dataframe значениями, которые составляют менее 80% от максимального значения в каждой группе. Как? - PullRequest
1 голос
/ 09 апреля 2019

У меня есть следующий фрейм данных:

d = {'group': ['a', 'b', 'c', 'b', 'b', 'c', 'a', 'b', 'a'],
'cum_sum': [1, 4, 3, 9, 15, 6, 3, 17, 4]}
df = pd.DataFrame(data=d)

Я хочу отфильтровать весь фрейм данных, чтобы хранить только записи в каждой группе, у которых cum_sum меньше максимального cum_sum x 0,8 в каждой группе.

Я пытался поиграться с параметрами лямбды и отфильтровать это:

grouped = df.groupby('group')
grouped.filter(lambda x: x[x.cum_sum] <= x[x.cum_sum.max()])

Но я просто понятия не имею, с чего начать ... Любые идеи ..?

ОБНОВЛЕНО В СООТВЕТСТВИИ С КОММЕНТАРИИ!

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

Вы можете использовать boolean indexing:

df1 = df[df['cum_sum'].lt(df.groupby('group')['cum_sum'].transform('max') * 0.8)]
print (df1)
  group  cum_sum
0     a        1
1     b        4
2     c        3
3     b        9
6     a        3

Объяснение

Первое использование GroupBy.transform с max для серий такого же размера, как у оригинала DataFrame:

print (df.groupby('group')['cum_sum'].transform('max'))
0     4
1    17
2     6
3    17
4    17
5     6
6     4
7    17
8     4
Name: cum_sum, dtype: int64

кратно константе:

print (df.groupby('group')['cum_sum'].transform('max') * 0.8)
0     3.2
1    13.6
2     4.8
3    13.6
4    13.6
5     4.8
6     3.2
7    13.6
8     3.2
Name: cum_sum, dtype: float64

Сравнить по Series.lt для <:

print (df['cum_sum'].lt(df.groupby('group')['cum_sum'].transform('max') * 0.8))
0     True
1     True
2     True
3     True
4    False
5    False
6     True
7    False
8    False
Name: cum_sum, dtype: bool
0 голосов
/ 09 апреля 2019

Не очень элегантное решение, но оно работает.

grouped = df.groupby('group').max()['cum_sum'].reset_index()
grouped.columns=['group','max_cum_sum']
df = df.merge(grouped)
df = df.loc[df['cum_sum'] <= df['max_cum_sum']*0.8]
...