Pandas предупреждение агрегации (FutureWarning: использование dict с переименованием устарело)

Я пытаюсь сделать некоторые агрегации в кадре данных pandas. Вот пример кода:

import pandas as pd

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0]})

df.groupby(["User"]).agg({"Amount": {"Sum": "sum", "Count": "count"}})

Out[1]: 
      Amount      
         Sum Count
User              
user1   18.0     2
user2   20.5     3
user3   10.5     1

Что генерирует следующее предупреждение:

FutureWarning: использование dict с переименованием устарело и будет удалены в будущей версии return super (DataFrameGroupBy, self).aggregate(arg, * args, ** kwargs)

Как я могу избежать этого?

Ответы

Ответ 1

Используйте groupby apply и верните серию для переименования столбцов

Используйте метод groupby apply для выполнения агрегации, которая

  • Переименовывает столбцы
  • Позволяет пробелы в именах
  • Позволяет вам заказывать возвращенные столбцы любым способом, который вы выбираете
  • Позволяет взаимодействовать между столбцами
  • Возвращает индекс одного уровня, а не MultiIndex

Для этого:

  • создайте пользовательскую функцию, которую вы передаете в apply
  • Эта настраиваемая функция передается каждой группе в виде DataFrame
  • Возврат серии
  • Индексом серии будут новые столбцы

Создание поддельных данных

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1", "user3"],
                  "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0, 9],
                  'Score': [9, 1, 8, 7, 7, 6, 9]})

введите описание изображения здесь

создать пользовательскую функцию, которая возвращает серию
Переменной x внутри my_agg является DataFrame

def my_agg(x):
    names = {
        'Amount mean': x['Amount'].mean(),
        'Amount std':  x['Amount'].std(),
        'Amount range': x['Amount'].max() - x['Amount'].min(),
        'Score Max':  x['Score'].max(),
        'Score Sum': x['Score'].sum(),
        'Amount Score Sum': (x['Amount'] * x['Score']).sum()}

    return pd.Series(names, index=['Amount range', 'Amount std', 'Amount mean',
                                   'Score Sum', 'Score Max', 'Amount Score Sum'])

Передайте эту настраиваемую функцию методу groupby apply

df.groupby('User').apply(my_agg)

введите описание изображения здесь

Большой недостаток заключается в том, что эта функция будет намного медленнее, чем agg для cythonized aggregations

Использование словаря с методом groupby agg

Использование словаря словарей было удалено из-за его сложности и несколько неоднозначности. Существует текущее обсуждение о том, как улучшить эту функциональность в будущем в github. Здесь вы можете напрямую обращаться к агрегаторному столбцу после группового вызова. Просто передайте список всех агрегирующих функций, которые вы хотите применить.

df.groupby('User')['Amount'].agg(['sum', 'count'])

Выход

       sum  count
User              
user1  18.0      2
user2  20.5      3
user3  10.5      1

По-прежнему можно использовать словарь, чтобы явно обозначать разные агрегации для разных столбцов, например, если был другой числовой столбец с именем Other.

df = pd.DataFrame({"User": ["user1", "user2", "user2", "user3", "user2", "user1"],
              "Amount": [10.0, 5.0, 8.0, 10.5, 7.5, 8.0],
              'Other': [1,2,3,4,5,6]})

df.groupby('User').agg({'Amount' : ['sum', 'count'], 'Other':['max', 'std']})

Выход

      Amount       Other          
         sum count   max       std
User                              
user1   18.0     2     6  3.535534
user2   20.5     3     5  1.527525
user3   10.5     1     4       NaN