Подтвердить что ты не робот

Несколько агрегатов одного столбца с использованием pandas GroupBy.agg()

Учитывая следующий (полностью перебитый) пример фрейма данных

import pandas as pd
import datetime as dt
df = pd.DataFrame({
         "date"    :  [dt.date(2012, x, 1) for x in range(1, 11)], 
         "returns" :  0.05 * np.random.randn(10), 
         "dummy"   :  np.repeat(1, 10)
})

Существует ли существующий встроенный способ применения двух разных функций агрегирования к одному и тому же столбцу без необходимости многократного вызова agg?

Синтаксически неправильный, но интуитивно правильный способ сделать это:

# Assume 'function1' and 'function2' are defined for aggregating.
df.groupby("dummy").agg({"returns":function1, "returns":function2})

Очевидно, что Python не позволяет дублировать ключи. Есть ли другой способ выражения ввода в agg? Возможно, список кортежей [(column, function)] будет работать лучше, чтобы несколько функций применялись к одному столбцу? Но похоже, что он принимает только словарь.

Есть ли обходной путь для этого помимо определения вспомогательной функции, которая просто применяет обе функции внутри нее? (Как это будет работать с агрегацией?)

4b9b3361

Ответ 1

Вы можете просто передать функции в виде списка:

In [20]: df.groupby("dummy").agg({"returns": [np.mean, np.sum]})
Out[20]: 
        returns          
            sum      mean

dummy                    
1      0.285833  0.028583

или как словарь:

In [21]: df.groupby('dummy').agg({'returns':
                                  {'Mean': np.mean, 'Sum': np.sum}})
Out[21]: 
        returns          
            Sum      Mean
dummy                    
1      0.285833  0.028583

Ответ 2

Что-то вроде этой работы:

In [7]: df.groupby('dummy').returns.agg({'func1' : lambda x: x.sum(), 'func2' : lambda x: x.prod()})
Out[7]: 
              func2     func1
dummy                        
1     -4.263768e-16 -0.188565

Ответ 3

Панды> = 0,25: Именованная Агрегация

Pandas изменил поведение GroupBy.agg в пользу более интуитивного синтаксиса для указания именованных агрегатов. См. Раздел 0.25 документации по улучшениям, а также соответствующие выпуски GitHub GH18366 и GH26512.

Из документации,

Для поддержки агрегирования по конкретным столбцам с контролем над именами выходных столбцов pandas принимает специальный синтаксис в GroupBy.agg(), известный как "именованная агрегация", где

  • Ключевыми словами являются имена выходных столбцов.
  • Значения - это кортежи, первый элемент которых является столбцом для выбора, а второй элемент является агрегацией, применяемой к этому столбцу. Pandas предоставляет pandas.NamedAgg namedtuple с полями ['column', 'aggfunc'], чтобы прояснить аргументы. Как обычно, агрегация может быть вызываемым или строковым псевдонимом.

Теперь вы можете передать кортеж через аргументы ключевых слов. Кортежи следуют формату (<colName>, <aggFunc>).

import pandas as pd

pd.__version__                                                                                                                            
# '0.25.0.dev0+840.g989f912ee'

# Setup
df = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                   'height': [9.1, 6.0, 9.5, 34.0],
                   'weight': [7.9, 7.5, 9.9, 198.0]
})

df.groupby('kind').agg(
    max_height=('height', 'max'), min_weight=('weight', 'min'),)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

Кроме того, вы можете использовать pd.NamedAgg (по сути, именованный кортеж), который делает вещи более явными.

df.groupby('kind').agg(
    max_height=pd.NamedAgg(column='height', aggfunc='max'), 
    min_weight=pd.NamedAgg(column='weight', aggfunc='min')
)

      max_height  min_weight
kind                        
cat          9.5         7.9
dog         34.0         7.5

Для Series это еще проще, просто передайте aggfunc ключевому слову arguments.t

df.groupby('kind')['height'].agg(max_height='max', min_height='min')    

      max_height  min_height
kind                        
cat          9.5         9.1
dog         34.0         6.0       

Наконец, если ваши имена столбцов не являются допустимыми идентификаторами Python, используйте словарь с распаковкой:

df.groupby('kind')['height'].agg(**{'max height': 'max', ...})

Панды <0,25

В более поздних версиях панд, ведущих к значению 0,24, при использовании словаря для указания имен столбцов для вывода агрегации вы получите FutureWarning:

df.groupby('dummy').agg({'returns': {'Mean': 'mean', 'Sum': 'sum'}})
# FutureWarning: using a dict with renaming is deprecated and will be removed 
# in a future version

Использование словаря для переименования столбцов устарело в v0.20. В более поздних версиях панд это можно указать проще, передав список кортежей. При указании функций таким способом все функции для этого столбца должны быть указаны в виде кортежей пар (имя, функция).

df.groupby("dummy").agg({'returns': [('op1', 'sum'), ('op2', 'mean')]})

        returns          
            op1       op2
dummy                    
1      0.328953  0.032895

Или же,

df.groupby("dummy")['returns'].agg([('op1', 'sum'), ('op2', 'mean')])

            op1       op2
dummy                    
1      0.328953  0.032895