2016-11-02 4 views
2

Я пытаюсь использовать groupby, nlargest и sum функции в Pandas вместе, но проблема с его работой.Pandas groupby самая крупная сумма

State County Population 
Alabama a   100 
Alabama b   50 
Alabama c   40 
Alabama d   5 
Alabama e   1 
... 
Wyoming a.51  180 
Wyoming b.51  150 
Wyoming c.51  56 
Wyoming d.51  5 

Я хочу использовать groupby для выбора государством, а затем получить 2 верхних округов по численности населения. Затем используйте только те из трех верхних номеров графства, чтобы получить сумму для этого состояния.

В конце концов, у меня будет список, который будет иметь состояние и население (из его двух верхних уездов).

Я могу получить groupby и nlargest, но получение суммы nlargest(2) - вызов.

линия у меня сейчас просто: df.groupby('State')['Population'].nlargest(2)

ответ

13

Вы можете использовать apply после выполнения groupby:

df.groupby('State')['Population'].apply(lambda grp: grp.nlargest(2).sum()) 

Я думаю, что этот вопрос вы испытываете, что df.groupby('State')['Population'].nlargest(2) возвратит DataFrame, поэтому вы больше не можете выполнять операции на уровне группы. В общем случае, если вы хотите выполнить несколько операций в группе, вам нужно будет использовать apply/agg.

Полученный выход:

State 
Alabama 150 
Wyoming 330 

РЕДАКТИРОВАТЬ

Немного чище подход, как это было предложено @ cᴏʟᴅsᴘᴇᴇᴅ:

df.groupby('State')['Population'].nlargest(2).sum(level=0) 

Это немного медленнее, чем при использовании apply на больших DataFrames хоть.

Используя следующие настройки:

import numpy as np 
import pandas as pd 
from string import ascii_letters 

n = 10**6 
df = pd.DataFrame({'A': np.random.choice(list(ascii_letters), size=n), 
        'B': np.random.randint(10**7, size=n)}) 

я получаю следующие тайминги:

In [3]: %timeit df.groupby('A')['B'].apply(lambda grp: grp.nlargest(2).sum()) 
103 ms ± 1.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 

In [4]: %timeit df.groupby('A')['B'].nlargest(2).sum(level=0) 
147 ms ± 3.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) 

Чем медленнее производительность потенциально вызванное level kwarg в sum выполнения второй groupby под капотом.

+1

Вы должны исправить это, избавившись от применить, используя 'df.groupby («State») [«Population»]. nlargest (2) .sum (level = 0) ' –

+1

@ cᴏʟᴅsᴘᴇᴇᴅ: ваше предложенное решение' .nlargest (2) .sum (level = 0) 'на самом деле медленнее, чем использование' apply', когда размер файловой системы является существенным. «Уровень» kwarg в 'sum' выполняет вторую групповую операцию под капотом, которая, как я предполагаю, является источником дополнительных накладных расходов. – root

+1

Это удивительно. Таким образом, одна группа + применяет козыри двух групп. Узнал что-то новое, ура! –

2

Использование agg, группирования логика выглядит следующим образом:

df.groupby('State').agg({'Population': {lambda x: x.nlargest(2).sum() }})

Это приводит к другому объекту dataframe; которые вы можете запросить, чтобы найти самые густонаселенные государства и т.д.

  Population 
State 
Alabama 150 
Wyoming 330 
+0

Отсутствует фигурная скобка – diabolicfreak

+0

@diabolicfreak Спасибо, я отредактировал свой ответ. – aquaraga