DataError: Нет числовых типов, использующих среднюю статистическую функцию, но не сумму? - PullRequest
0 голосов
/ 30 апреля 2018

Мне было интересно, если кто-нибудь может помочь объяснить поведение ниже, используя agg ()

import numpy as np
import pandas as pd
import string

Инициализировать фрейм данных

df = pd.DataFrame(data=[list(string.ascii_lowercase)[0:5]*2,list(range(1,11)),list(range(11,21))]).T
df.columns = columns=['g','c1','c2']

df.sort_values(['g']).head(5)

g   c1  c2
0   a   1   11
5   a   6   16
1   b   2   12
6   b   7   17
2   c   3   13

В качестве примера я суммирую и усредняю ​​по c1 и c2, делая группу по g

Сценарий ошибки данных отсутствует:

f = { 'c1' : lambda g: df.loc[g.index].c2.sum() + g.sum(), 'c2' : lambda g: (df.loc[g.index].c1.sum() + g.sum())/(g.count()+df.loc[g.index].c1.count())} 
df = df.groupby('g',as_index=False).agg(f)

Ошибка с типом данных:

rnm_cols = dict(sum='Sum', mean='Mean') #, std='Std')
df = df.set_index(['g']).stack().groupby('g').agg(rnm_cols.keys()).rename(columns=rnm_cols)

Я получаю -> DataError: Нет числовых типов для агрегирования

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

df[['c1','c2']] = df[['c1','c2']].apply(lambda x: pd.to_numeric(x, errors='coerce'))

Однако я пытаюсь понять, почему агрегирование со средним Функция выдаёт такие ошибки?

1 Ответ

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

Это связано с тем, что GroupBy объекты обрабатывают различные методы агрегирования. На самом деле sum и mean обрабатываются по-разному (подробнее см. Ниже).

Но суть в том, что mean работает только для числовых типов, которых нет в вашем фрейме данных:

>>> df.dtypes
g     object
c1    object
c2    object
dtype: object

Применяя pd.to_numeric, вы конвертируете их в числовой тип, и agg работает.

Но давайте внимательнее посмотрим:

GroupBy.mean

Этот вызов функции отправляет self._cython_agg_general, который проверяет числовые типы, и в случае, если он не находит ни одного (как в вашем примере), он вызывает DataError. Хотя вызов self._cython_agg_general обернут в try/except, в случае GroupByError он просто повторно повышается, и DataError наследуется от GroupByError. Таким образом, исключение.

GroupBy.sum

Эта функция определяется по-другому, а именно здесь (через эта функция ). функция-обёртка аналогично отправляет в self._cython_agg_general, обернутую в try/except, но она не добавляет особого предложения для GroupByError s (хотя и не знаю, почему; возможно, это хороший вопрос для разработчиков , поэтому они могут унифицировать поведение GroupBy объектов). Поскольку self._cython_agg_general снова поднимает DataError, он войдет в предложение except Exception, для которого он возвращается к self.aggregate. Отсюда вы можете отследить его с помощью дюжины дополнительных вызовов функций, но в итоге он просто добавит отдельные элементы серии (которые хранятся как object s, но добавление в Python не является проблемой, поскольку они int на самом деле).

Резюме

Таким образом, все сводится к тому, как две функции агрегации обрабатывают исключения; mean ре-рейзит на DataError, но sum нет. «Почему» до сих пор остается открытым вопросом и для меня.

Смотри также

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...