Панди підсумовуються за групами, але виключають певні стовпці


88

Який найкращий спосіб зробити групування на фреймі даних Pandas, але виключити деякі стовпці з цієї групи? наприклад, у мене є такий фрейм даних:

Code   Country      Item_Code   Item    Ele_Code    Unit    Y1961    Y1962   Y1963
2      Afghanistan  15          Wheat   5312        Ha      10       20      30
2      Afghanistan  25          Maize   5312        Ha      10       20      30
4      Angola       15          Wheat   7312        Ha      30       40      50
4      Angola       25          Maize   7312        Ha      30       40      50

Я хочу згрупувати за стовпчиком Country і Item_Code і обчислити лише суму рядків, що потрапляють під стовпці Y1961, Y1962 та Y1963. Отриманий фрейм даних повинен виглядати так:

Code   Country      Item_Code   Item    Ele_Code    Unit    Y1961    Y1962   Y1963
2      Afghanistan  15          C3      5312        Ha      20       40       60
4      Angola       25          C4      7312        Ha      60       80      100

Зараз я роблю це:

df.groupby('Country').sum()

Однак це також додає значення в стовпці Item_Code. Чи можу я якось вказати, які стовпці включати в sum()операцію, а які виключати?

Відповіді:


117

Ви можете вибрати стовпці групи за допомогою:

In [11]: df.groupby(['Country', 'Item_Code'])[["Y1961", "Y1962", "Y1963"]].sum()
Out[11]:
                       Y1961  Y1962  Y1963
Country     Item_Code
Afghanistan 15            10     20     30
            25            10     20     30
Angola      15            30     40     50
            25            30     40     50

Зверніть увагу, що переданий список повинен бути підмножиною стовпців, інакше ви побачите KeyError.


1
Як включити кількість записів для кожної країни та коду товару в інший стовпець?
Sushant Kulkarni

Ви можете створити фіктивний стовпець перед групуванням, який просто містить 1. тоді сума буде підсумовувати ті, що створюють підрахунок.
Matt W.

Якщо ви просто хочете виключити стовпець або два, тоді ви отримаєте всі назви стовпців, як і listColumns = list(df.columns)тоді, ви видалите не потрібні вам стовпці listColumns.remove('Y1964')і, нарешті, зробите підсумок:df.groupby(['Country', 'Item_Code'])[listColumns].sum()
Роберто Стеллінг

Дуже дякую. Я можу змусити групу працювати, але не частину відбору. Список стовпців, які я вклав, є серед фреймів даних, але він продовжує піднімати ValueError:cannot reindex from a duplicate axis
Боуен Лю

@BowenLiu, якщо у вас є кілька стовпців з однаковим ім'ям, це покаже цю помилку. У цьому випадку вам доведеться використовувати iloc до або loc, щоб отримати потрібні стовпці, я думаю, вам доведеться це зробити до groupby.
Енді Хейден,

40

aggФункція зробить це для вас. Передайте стовпці та функціонуйте як dict зі стовпцем, вивід:

df.groupby(['Country', 'Item_Code']).agg({'Y1961': np.sum, 'Y1962': [np.sum, np.mean]})  # Added example for two output columns from a single input column

Тут відображатимуться лише група за стовпцями та вказані сукупні стовпці. У цьому прикладі я включив дві функції agg, застосовані до 'Y1962'.

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

df.groupby(['Code', 'Country', 'Item_Code', 'Item', 'Ele_Code', 'Unit']).agg({'Y1961': np.sum, 'Y1962': np.sum, 'Y1963': np.sum})

1
дякую, чи можна це узагальнити? У мене багато стовпців форми Y1961 ... тому я створюю такий список: yrs = ['Y' + str (x) для x в діапазоні (1961, 2010 + 1, 1)]. Чи може ваше рішення використовувати "yrs" всередині agg?
user308827

Мені дуже подобається ця ідея. Хитрість полягає у побудові цього дикту, значення якого є функцією numpy sum. І навпаки, якщо все, що ви хочете зробити, це підсумувати всі решту стовпців, ваше оригінальне рішення буде працювати, якщо всі групи за стовпцями будуть включені в групу за твердженням.
leroyJr

11

Якщо ви шукаєте більш узагальнений спосіб застосувати до багатьох стовпців, ви можете створити список назв стовпців і передати його як індекс згрупованого кадру даних. У вашому випадку, наприклад:

columns = ['Y'+str(i) for year in range(1967, 2011)]

df.groupby('Country')[columns].agg('sum')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.