Pandas groupby agg std NaN - PullRequest
       9

Pandas groupby agg std NaN

0 голосов
/ 12 мая 2018

Входы:

df['PopEst']
    .astype('float')
    .groupby(ContinentDict)
    .agg(['size','sum','mean','std']))

Выходы:

            size            sum                mean              std
Asia          5     2.898666e+09       5.797333e+08     6.790979e+08
Australia     1     2.331602e+07       2.331602e+07              NaN
Europe        6     4.579297e+08       7.632161e+07     3.464767e+07
North America 2     3.528552e+08       1.764276e+08     1.996696e+08
South America 1     2.059153e+08       2.059153e+08              NaN

Некоторые значения в столбце std оказываются NaN , еслиГруппа просто имеет одну строку, но я думаю, что эти значения должны быть 0, почему это так?

Ответы [ 2 ]

0 голосов
/ 24 июля 2018

Согласно документу , np.std(..., ddof=1) по умолчанию установите «дельта степень свободы» на 1. Чтобы решить вашу проблему, просто замените np.std на lambda x: np.std(x, ddof=0), тогда ваш NaN будетизменено на 0.

0 голосов
/ 12 мая 2018

pd.DataFrame.std предполагает по умолчанию 1 степень свободы, также известную как выборка стандартное отклонение. Это приводит к NaN результатам для групп с одним номером.

numpy.std, напротив, по умолчанию предполагает 0 степеней свободы, также известный как популяция стандартное отклонение. Это дает 0 для групп с одним номером.

Чтобы понять разницу между выборкой и населением, см. Поправка Бесселя .

Таким образом, вы можете указать numpy.std для вашего расчета. Обратите внимание, однако, что выходные данные будут отличаться, так как расчеты разные. Вот минимальный пример.

import pandas as pd, numpy as np

df = pd.DataFrame(np.random.randint(0, 9, (5, 2)))

def std(x): return np.std(x)

res = df.groupby(0)[1].agg(['size', 'sum', 'mean', std])

print(res)

   size  sum  mean       std
0                           
0     2   13   6.5       0.5
4     1    3   3.0       0.0
5     1    3   3.0       0.0
6     1    3   3.0       0.0

В качестве альтернативы, если вам требуется 1 степень свободы, вы можете использовать fillna для замены NaN значений на 0:

res = df.groupby(0)[1].agg(['size', 'sum', 'mean', 'std']).fillna(0)
...