Хобрук: Ваш путь к мастерству в программировании

pandas: добавьте общую строку для каждой подгруппы при группировании (особенно для неаддитивного метода, такого как `nunique`)

Легко получить многоуровневый групповой результат, подобный этому

                Max Speed
Animal Type
Falcon Captive      390.0
       Wild         350.0
Parrot Captive       30.0
       Wild          20.0

Код будет выглядеть как df.groupby(['animal', 'type'])['speed'].max()

Однако, если я хочу добавить общую строку в каждую подгруппу, чтобы создать что-то вроде этого

                Max Speed
Animal Type
Falcon Captive      390.0
       Wild         350.0
       overall      390.0
Parrot Captive       30.0
       Wild          20.0
       overall       30.0

Как мне это сделать?

Причина добавления строки подуровня заключается в том, что она позволяет выбирать категорию, когда я помещаю ее в инструменты BI для других коллег.

ОБНОВЛЕНИЕ: в приведенном выше примере я показываю с помощью max(), я также хочу знать, как это сделать с помощью user_id.nunique().


Прямо сейчас я получаю результат по 2 группам, а затем объединяю их. что-то вроде

df1 = df.groupby(['animal', 'type'])['speed'].max()
df2 = df.groupby(['animal'])['speed'].max()
##### ...  manually add `overall` index to df_2
df_total = pd.concat([df1, df2]).sort_index()

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


Ответы:


1

Вы можете сделать это с 2 concat, начиная с вашего результата groupby.


g = df.groupby(level=0).max()

m = pd.concat([g], keys=['overall'], names=['Type']).swaplevel(0, 1)

pd.concat([df, m], axis=0).sort_index(level=0)

                Max Speed
Animal Type
Falcon Captive      390.0
       Wild         350.0
       overall      390.0
Parrot Captive       30.0
       Wild          20.0
       overall       30.0
22.07.2019
  • Что, если я использую что-то вроде .nunique() в качестве метода агрегации, будет ли этот подход по-прежнему действителен? 24.07.2019

  • 2

    Адаптация из этого ответа:

    # Create data
    np.random.seed(2019)
    df = pd.DataFrame({ 
        'animal' : np.repeat(['Falcon', 'Parrot'], 10),
        'type' : np.tile(['Captive','Wild'], 10),
        'speed' : np.random.uniform(10,20,20)})
    df.loc[df['animal'] == 'Falcon', 'speed'] = df['speed'] * 3
    df.loc[df['type'] == 'Captive', 'speed'] = df['speed'] * .7
    
    # Summary table
    table = df.pivot_table(index=['animal','type'], values='speed', aggfunc=max)
    # or... table = df.groupby(['animal','type'])['speed'].max().to_frame()
    
    pd.concat([d.append(d.max().rename((k, 'Total')))
               for k, d in table.groupby(level=0) 
              ]).append(table.max().rename(('Grand','Total')))
    

    дает

                        speed
    animal type              
    Falcon Captive  39.973127
           Wild     57.096185
           Total    57.096185
    Parrot Captive  10.167126
           Wild     19.847235
           Total    19.847235
    Grand  Total    57.096185
    

    Если вам не нужна общая сумма, вы можете удалить .append(table.max().rename(('Grand','Total'))).

    22.07.2019

    3

    Эффективный способ:

    df1 = df.groupby(['animal', 'type'])['speed'].max()
    
    pd.concat([df1.reset_index(level='type'), pd.DataFrame(df1.max(level=0)).assign(
        type='overall')]).set_index('type',append=True).sort_index(level=0)
    

    Из:

                   speed
    animal type              
    Falcon Captive  19.238636
           Wild     19.607617
           overall  19.607617
    Parrot Captive  18.386352
           Wild     17.735187
           overall  18.386352
    
    22.07.2019
  • Что, если я использую что-то вроде .nunique() в качестве агрегатного метода, будет ли этот подход по-прежнему действителен? 24.07.2019
  • тоже должно работать. В общем, любая агрегация работает. 24.07.2019
  • Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.