Пандам не удается агрегировать со списком функций агрегирования - PullRequest
0 голосов
/ 26 февраля 2019

Как мне указать пользовательские функции агрегирования, чтобы они работали правильно, когда используются в аргументах списка pandas.DataFrame.aggregate?

При заданном двухколоночном фрейме данных в пандах ...

import pandas as pd
import numpy as np
df = pd.DataFrame(index=range(10))
df['a'] = [ 3 * x for x in range(10) ]
df['b'] = [ 1 -2 * x for x in range(10) ]

... агрегирование по списку спецификаций функции агрегирования не является проблемой:

def ok_mean(x):
  return x.mean()

df.aggregate(['mean', np.max, ok_mean])
               a    b
mean        13.5    -8.0
amax        27.0    1.0
ok_mean     13.5    -8.0

, но когда агрегация указана как (лямбда или именованная) функция, агрегирование не удается:

def nok_mean(x):
  return np.mean(x)

df.aggregate([lambda x:  np.mean(x), nok_mean])
                   a                 b
   <lambda> nok_mean <lambda> nok_mean
0   0.0      0.0     1.0     1.0
1   3.0      3.0    -1.0    -1.0
2   6.0      6.0    -3.0    -3.0
3   9.0      9.0    -5.0    -5.0
4   12.0    12.0    -7.0    -7.0
...

Смешивание агрегирующих и неагрегирующих спецификаций приводит к ошибкам:

df.aggregate(['mean', nok_mean])
~/anaconda3/envs/tsa37_jup/lib/python3.7/site-packages/pandas/core/base.py in _aggregate_multiple_funcs(self, arg, _level, _axis)
    607         # if we are empty
    608         if not len(results):
--> 609             raise ValueError("no results")
    610 

При использовании функции агрегирования напрямую (не в списке) вы получите ожидаемый результат:

df.aggregate(nok_mean)
a    13.5
b    -8.0
dtype: float64

Это ошибка или я что-то упускаю в способе определения функций агрегирования?В моем реальном проекте я использую более сложные функции агрегирования (такие как этот процентиль ).Итак, мой вопрос:

Как мне указать настраиваемую функцию агрегирования, чтобы обойти эту ошибку?

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

df.expanding().aggregate(['mean', nok_mean])
## returns cumulative aggregation results as expected

Версия Pandas: 0.23.4

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

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

def ok_mean(x):
  return np.mean(x.values)

def ok_mean2(x):
  if not isinstance(x,pd.Series):
    raise ValueError('need Series argument')
  return np.mean(x)

df.aggregate(['mean', ok_mean, ok_mean2])

Похоже, что в этом случае (в аргументе списка до pandas.DataFrame.aggregate) pandasсначала пытается применить функцию агрегирования к каждой точке данных, и с момента сбоя возвращается к правильному поведению (обратный вызов с серией, подлежащей агрегации).

Использование декоратора для аргументов Series:

def assert_argtype(clazz):
    def wrapping(f):
        def wrapper(s):
            if not isinstance(s,clazz):
                raise ValueError('needs %s argument' % clazz)
            return f(s)
        return wrapper
    return wrapping

@assert_argtype(pd.Series)
def nok_mean(x):
    return np.mean(x)

df.aggregate([nok_mean])
## OK now, decorator fixed it!
0 голосов
/ 26 февраля 2019

Основываясь на ответах на этот вопрос Панды - агрегат DataFrame ведет себя странно

Похоже, это потому, что вы вызываете np.mean непосредственно для отдельных значений, а не для всей серии вкадр данных.Изменение функции на

def nok_mean(x):
    return x.mean()

Теперь позволяет применять несколько функций:

df.agg(['mean', nok_mean])

Возвращает

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