2017-02-03 7 views
1

Я пытаюсь понять пример из книги Python для анализа данных Уэса МакКинни. Я просмотрел поваренную книгу pandas, документацию и SO, но не могу найти такой пример.Понимание apply and groupby in Pandas

В примере рассмотрена база данных Федеральной избирательной комиссии 2012 года (https://github.com/wesm/pydata-book/blob/master/ch09.ipynb). Приведенный ниже код определяет верхнюю работу доноров, жертвуя Обаме и Ромни.

Я пытаюсь понять, как функция принимает объект groupby и выполняет на нем другую операцию groupby. Когда я запускаю это вне функции, я получаю сообщение об ошибке. Может ли кто-нибудь пролить свет на это поведение?

Спасибо,

Iwan

# top donor occupations donating to Obama or Romney 
def get_top_amounts(group, key, n = 5): 
    totals = group.groupby(key)['contb_receipt_amt'].sum() 

    return totals.sort_values(ascending = False)[:n] 

# first group by candidate 
grouped = fec_mrbo.groupby('cand_nm') 

# for each group, group again by contb_receipt_amt so we have a hierarchical index 
# take the contribution amount 
# then return the total amount for each occupation by cand sorted to give top n 
grouped.apply(get_top_amounts, 'contbr_occupation', n= 5) 

Результат выглядит следующим образом

cand_nm  contbr_occupation      
Obama, Barack RETIRED         25270507.23 
       ATTORNEY         11126932.97 
       INFORMATION REQUESTED      4849801.96 
       HOMEMAKER         4243394.30 
       PHYSICIAN         3732387.44 
       LAWYER          3159391.87 
       CONSULTANT         2459812.71 
Romney, Mitt RETIRED         11266949.23 
       INFORMATION REQUESTED PER BEST EFFORTS 11173374.84 
       HOMEMAKER         8037250.86 
       ATTORNEY         5302578.82 
       PRESIDENT         2403439.77 
       EXECUTIVE         2230653.79 
       C.E.O.          1893931.11 

ответ

1

При использовании apply на сгруппированных dataframe вы на самом деле Перебор групп и передать каждой группе функцию, которую вы применяете. Давайте рассмотрим простой пример:

import pandas as pd 
df = pd.DataFrame({'col1': [1,1,1,1,2,2,2,2], 
        'col2': ['a','b','a','b','a','b','a','b'], 
        'value': [1,2,3,4,5,6,7,8]}) 
grouped = df.groupby('col1') 

Теперь давайте создадим простую функцию, которая позволяет нам увидеть, что получение передается функции:

def print_group(group): 
    print(group) 
    print('=' * 10) 

grouped.apply(print_group) 
    col1 col2 value 
0  1 a  1 
1  1 b  2 
2  1 a  3 
3  1 b  4 
========== 
    col1 col2 value 
0  1 a  1 
1  1 b  2 
2  1 a  3 
3  1 b  4 
========== 
    col1 col2 value 
4  2 a  5 
5  2 b  6 
6  2 a  7 
7  2 b  8 
========== 

Как вы можете видеть, каждая группа становится передается функция как отдельный блок данных. И, конечно, вы можете применить все обычные функции к этому подмножеству. Тот факт, что вы видите первую группу дважды, объясняется внутренними причинами и не может быть изменен, это не ошибка;).

Давайте создадим еще одну функцию для доказательства этого:

def second_group_sum(group): 
    res = group.groupby('col2').value.sum() 
    print(res) 
    print('=' * 10) 
    return res 

grouped.apply(second_group_sum) 
col2 
a 4 
b 6 
Name: value, dtype: int64 
========== 
col2 
a 4 
b 6 
Name: value, dtype: int64 
========== 
col2 
a 12 
b 14 
Name: value, dtype: int64 
========== 

Можно даже пойти дальше и сделать группу применить-группы применяются-группы применяются и т.д. и т.п ...

Я надеюсь, что это помогает немного понимаю, что происходит.

Кстати, если вы используете ipdb (инструмент отладки), вы можете установить точку останова в прикладной функции a, взаимодействовать с групповым фреймворком.

+0

Thanks Jan! Поэтому, чтобы убедиться, что я получил это. Сгруппированная переменная, определенная выше, является объектом DataFrameGroupBy. Но когда действует функция apply, она ведет себя как DataFrame. Это то, что позволяет выполнять вторую группу, как вы делали в second_group_sum. –

+0

Да, 'grouped' является объектом DataFrameGroupBy. И что он делает, когда вы используете 'apply (function)', в значительной степени разделяет базовый DataFrame на несколько DataFrames, по одному для каждой группы. –