Панды: почему панды.Серии.std () отличается от numpy.станд()

другое обновление: решено (см. комментарии и мой собственный ответ).

Update: это то, что я пытаюсь объяснить.

>>> pd.Series([7,20,22,22]).std()
7.2284161474004804
>>> np.std([7,20,22,22])
6.2599920127744575

ответ: это объясняется исправление Бесселя, N-1 вместо N в знаменателе формулы стандартного отклонения. Я бы хотел, чтобы панды использовали ту же конвенцию, что и numpy.


существует соответствующее обсуждение здесь, но их предложения не работает.

у меня есть данные о многих различных ресторанах. Вот мой фрейм данных (представьте себе более одного ресторана, но эффект воспроизводится только с одним):

>>> df
restaurant_id  price
id                      
1           10407      7
3           10407     20
6           10407     22
13          10407     22

вопрос: r.mi.groupby('restaurant_id')['price'].mean() возвращает цену означает для каждого ресторана. Я хочу получить стандартные отклонения. Однако,r.mi.groupby('restaurant_id')['price'].std() возвращает неправильные значения.

как вы можете видеть, для простоты я извлек только один ресторан с четырьмя блюдами. Я хочу найти стандартное отклонение цены. Просто чтобы убедиться:

>>> np.mean([7,20,22,22])
17.75
>>> np.std([7,20,22,22])
6.2599920127744575

мы можем получить те же самые (правильные) значения

>>> np.mean(df)
restaurant_id    10407.00
price               17.75
dtype: float64
>>> np.std(df)
restaurant_id    0.000000
price            6.259992
dtype: float64

(конечно, игнорируйте средний идентификатор ресторана.), Очевидно, np.std(df) это не решение, когда у меня есть более одного ресторана. Поэтому я использую groupby.

>>> df.groupby('restaurant_id').agg('std')
                  price
restaurant_id          
10407          7.228416

что?! 7.228416 не 6.259992.

давайте попробуем еще раз.

>>> df.groupby('restaurant_id').std()

же вещь.

>>> df.groupby('restaurant_id')['price'].std()

то же самое.

>>> df.groupby('restaurant_id').apply(lambda x: x.std())

то же самое.

однако, это работает:

for id, group in df.groupby('restaurant_id'):
  print id, np.std(group['price'])

вопрос: есть ли правильный способ агрегировать фрейм данных, поэтому я получу новый временной ряд со стандартными отклонениями для каждого ресторана?

2 ответов


Я вижу. Панды использует исправление Бесселя по умолчанию -- то есть формула стандартного отклонения с N-1 вместо N в знаменателе. Как Бехзад.Нури указал в комментариях,

pd.Series([7,20,22,22]).std(ddof=0)==np.std([7,20,22,22])

попробовать df.groupby('restaurant_id').std(ddof=0) которая составляет исправление Бесселя как поясняется в панды документация.