了解Pandas中的apply和groupby

时间:2017-02-03 10:11:07

标签: python pandas group-by apply

我试图理解Wes McKinney的Python for Data Analysis一书中的一个例子。我已经查看了大熊猫的食谱,文档和SO,但是找不到像这样的例子。

该示例着眼于2012年联邦选举委员会数据库(https://github.com/wesm/pydata-book/blob/master/ch09.ipynb)。下面的代码确定了捐赠给奥巴马和罗姆尼的最高捐助者职业。

我正在努力理解该函数如何获取groupby对象并对其执行另一个groupby操作。当我在函数外部运行时,我得到一个错误。有人可以对这种行为有所了解吗?

谢谢,

伊万

# 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 个答案:

答案 0 :(得分:2)

当您在分组数据框上使用apply时,您实际上正在迭代这些组并将每个组传递给您正在应用的函数。 让我们看一个简单的例子:

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
==========

您甚至可以更进一步,进行group-apply-group-apply-group-apply等等......

我希望这有助于理解正在发生的事情。

顺便说一句,如果你使用ipdb(调试工具),你可以在应用函数中设置一个断点,与组数据帧进行交互。