Выполните операцию на соответствующем сгруппированном кадре данных Pandas. - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть датафрейм:

User Numbers A 0 A 4 A 5 B 0 B 0 C 1 C 3

Я хочу выполнить операцию с соответствующими сгруппированными данными.Например, если я хочу удалить все Users, которые имеют Number 0, он должен выглядеть следующим образом:

User Numbers A 0 A 4 A 5 C 1 C 3

, поскольку все Numbers из User Bравно 0.

Или, например, если я хочу найти дисперсию чисел всех пользователей, она должна выглядеть следующим образом:

Users Variance A 7 B 0 C 2

Это означаеттолько Numbers для A рассчитывается для нахождения дисперсии A и т. д.

Существует ли общий способ выполнения всех этих вычислений для сопоставления сгруппированных данных?

1 Ответ

0 голосов
/ 25 апреля 2018

Требуется 2 различные операции - фильтрация по группам и агрегация по группам .

Фильтрация :

Длялучшую производительность лучше использовать transform для логической маски и фильтрации по boolean indexing.

df1 = df[~df['Number'].eq(0).groupby(df['User']).transform('all')]
print (df1)
  User  Number
0    A       0
1    A       4
2    A       5
5    C       1
6    C       3

Шаги:

1. Сначала создайте логическую серию, сравнив Number с eq:

print (df['Number'].eq(0))
0     True
1    False
2    False
3     True
4     True
5    False
6    False
Name: Number, dtype: bool

2.Затем используйте синтаксический сахар - groupby в другом столбце и transform функция all для проверки, все ли True с на группу и transform для маски того же размера, что и оригинал DataFrame:

print (df['Number'].eq(0).groupby(df['User']).transform('all'))
0    False
1    False
2    False
3     True
4     True
5    False
6    False
Name: Number, dtype: bool

3.Инвертируйте маску Boolen с помощью ~:

print (~df['Number'].eq(0).groupby(df['User']).transform('all'))
0     True
1     True
2     True
3    False
4    False
5     True
6     True
Name: Number, dtype: bool

4.Фильтр:

print (df[~df['Number'].eq(0).groupby(df['User']).transform('all')])
  User  Number
0    A       0
1    A       4
2    A       5
5    C       1
6    C       3

Еще одно более медленное решение в большом DataFrame с фильтром и той же логикой, что и в первом решении:

df2 = df.groupby('User').filter(lambda x: ~x['Number'].eq(0).all())
print (df2)
  User  Number
0    A       0
1    A       4
2    A       5
5    C       1
6    C       3

Агрегирование :

Для упрощенияагрегирование по одному столбцу с одной функцией агрегирования, например GroupBy.var использование:

df3 = df.groupby('User', as_index=False)['Number'].var()
print (df3)
  User  Number
0    A       7
1    B       0
2    C       2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...