前言

“split-apply-combine”(拆分-应用-合并)很好地描述了分组运算的整个过程。

分组运算的第一个阶段,pandas对象(无论是Series、DataFrame还是其他的)中的数据会根据所提供的一个或多个键被拆分(split)为多组。

拆分操作是在对象的特定轴上执行的。例如,DataFrame可以在其行(axis=0)或列(axis=1)上进行分组。

然后,将一个函数应用(apply)到各个分组并产生一个新值。

最后,所有这些函数的执行结果会被合并(combine)到最终的结果对象中。结果对象的形式一般取决于数据上所执行的操作。

下图,大致说明了一个简单的分组聚合过程:


python dataframe拆分un python dataframe分组_groupby python


分组键

分组键可以有多种形式,且类型不必相同:

  • 列表或数组,其长度与待分组的轴一样。
  • 表示DataFrame某个列名的值。
  • 字典或Series,给出待分组轴上的值与分组名之间的对应关系。
  • 函数,用于处理轴索引中的各个标签。

注意:后三种都只是快捷方式而已,其最终目的仍然是产生一组用于拆分对象的值。

先了解一下表格型数据集(以DataFrame的形式):

In [1]: import numpy as npIn [2]: import pandas as pdIn [3]: from pandas import Series,DataFrameIn [4]: df=DataFrame({'key1':['a','a','b','b','a'],                      'key2':['one','two','one','two','one'],                      'data1':np.random.randn(5),                      'data2':np.random.randn(5)})In [5]: dfOut[5]:   key1 key2     data1     data20    a  one -0.549915 -1.5673421    a  two -0.037543 -0.8345762    b  one -1.267072  1.6288813    b  two  0.976757 -1.5496644    a  one  2.423714  1.791845

假设想要按key1进行分组,并计算data1列的平均值。实现方式:访问data1,并根据key1调用groupby:

In [6]: grouped=df['data1'].groupby(df['key1'])In [7]: groupedOut[7]:

变量grouped是一个GroupBy对象。它实际上还没有进行任何计算,只是含有一些有关分组键df[‘key1’]的中间数据而已。换句话说,该对象已经有了接下来对各组执行运算所需的一切信息。例如,可以调用GroupBy的mean方法来计算分组平均值:

In [8]: grouped.mean()Out[8]: key1a    0.612085b   -0.145158Name: data1, dtype: float64

四种分组键使用方法,具体如下:


python dataframe拆分un python dataframe分组_groupby python_02


一次传入多个数组

In [9]: means=df['data1'].groupby([df['key1'],df['key2']]).mean()In [10]: meansOut[10]: key1  key2a     one     0.936899      two    -0.037543b     one    -1.267072      two     0.976757Name: data1, dtype: float64

通过两个键对数据进行了分组,得到的Series具有一个层次化索引(由唯一的键对组成):

In [11]: means.unstack()Out[11]: key2       one       twokey1                    a     0.936899 -0.037543b    -1.267072  0.976757

分组键可以是任何长度适当的数组

In [12]: states=np.array(['Ohio','California','California','Ohio','Ohio'])In [13]: years=np.array([2005,2005,2006,2005,2006])In [14]: df['data1'].groupby([states,years]).mean()Out[14]: California  2005   -0.037543            2006   -1.267072Ohio        2005    0.213421            2006    2.423714Name: data1, dtype: float64

将列名(可以是字符串、数字或其他python对象)用作分组键

In [15]: df.groupby('key1').mean()Out[15]:          data1     data2key1                    a     0.612085 -0.203358b    -0.145158  0.039609

在执行df.groupby('key1').mean()时,结果中没有key2列。这是因为df[‘key2’]不是数值数据(俗称“麻烦列”),所以被从结果中排除了。默认情况下,所有数据列都会被整合,虽然有时会被过滤为一个子集。

In [16]: df.groupby(['key1','key2']).mean()Out[16]:               data1     data2key1 key2                    a    one   0.936899  0.112251     two  -0.037543 -0.834576b    one  -1.267072  1.628881     two   0.976757 -1.549664

GroupBy的size方法

返回一个含有分组大小的Series:

In [17]: df.groupby(['key1','key2']).size()Out[17]: key1  key2a     one     2      two     1b     one     1      two     1dtype: int64