Как я могу использовать pandas agg для суммирования логических значений и всегда получать числа как результат? - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть фрейм данных со столбцом типа bool. Я хотел бы получить количество значений True для идентификатора, используя функции pandas 'groupby и agg. Я делал это несколько раз, но, похоже, тип результирующего столбца зависит от фрейма данных. Вот пример:

import pandas as pd    
d = {'id': [1, 1, 2, 3], 'bool': [True, False, False, True]}
df = pd.DataFrame(data=d)

print(df.groupby(['id']).agg({'bool': 'sum'}))

Вывод, который я получаю из этого кода:

   id   bool
0   1   True
1   2  False
2   3   True

Это не то, что я хочу. Теперь, если agg попытается сложить два значения True:

import pandas as pd    
d = {'id': [1, 1, 2, 3], 'bool': [True, True, False, True]}
df = pd.DataFrame(data=d)

print(df.groupby(['id']).agg({'bool': 'sum'}))

Тогда я получу:

   id                 bool
0   1                 2.00
1   2                 0.00
2   3                 1.00

Вот как я хочу.

Я видел ситуации в котором несколько строк имеют тип bool, тогда как другие имеют тип float. Кажется, это связано с количеством сгруппированных строк: если только одна строка, то она показывает значение bool; если их больше одного, результирующий тип - float. Я хотел бы, чтобы результирующие агрегированные столбцы всегда имели тип float.

Pandas версия 1.0.1

Ответы [ 3 ]

0 голосов
/ 03 апреля 2020

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

import pandas as pd    
d = {'id': [1, 1, 2, 3], 'bool': [True, False, False, True]}
df = pd.DataFrame(data=d)
print(df.groupby(['id'])['bool'].sum().astype(float))

Получает выходные данные

id
1    1.0
2    0.0
3    1.0
Name: bool, dtype: float64
0 голосов
/ 03 апреля 2020

Существует специальная функция Numpy для подсчета ненулевых ячеек ( True считается 1 , False как 0 ). Таким образом, вы можете запустить:

df.groupby(['id']).bool.agg(lambda gr: np.count_nonzero(gr))

Я предполагаю, что вы хотите целое число число True значений. В противном случае добавьте .astype(float).

0 голосов
/ 03 апреля 2020

Вы можете использовать typecast для плавания . Используйте reset_index, если вам нужен отдельный столбец для индекса в конце

df.groupby(['id']).agg({'bool': 'sum'}).astype(float).reset_index()

Пример:

>>> import pandas as pd    
>>> d = {'id': [1, 1, 2, 3], 'bool': [True, True, False, True]}
>>> df = pd.DataFrame(data=d)
>>> 
>>> df.groupby(['id']).agg({'bool': 'sum'}).astype(float).reset_index()
   id  bool
0   1   2.0
1   2   0.0
2   3   1.0
>>> 
...