第10章 数据聚合与分组运算

10.1 groupby机制

将数据集进行分组并对各组应用一个函数通常书数据分析工作中的重要环节

"split-apply-combine"(拆分-应用-合并):对pandans等对象的某一个轴拆分成多个组,在对各个组应用函数,将各组得到的结果合并到一个新的对象中

第10章 数据聚合与分组运算_第1张图片
image.png

按照列key1进行分组,并求出每组的平均值

grouped=df.groupby('key1')
grouped.mean()
第10章 数据聚合与分组运算_第2张图片
image.png
df
第10章 数据聚合与分组运算_第3张图片
image.png

按照key1对data1的数据进行分组求平均值:

df['data1'].groupby(df['key1']).mean()
image.png

Series根据分组键进行聚合,再进行函数运算后返回一个新的Series对象
分组键也可以是列表

df['data1'].groupby([df['key1'],df['key2']]).mean()
第10章 数据聚合与分组运算_第4张图片
image.png

实际上,分组键可以是任何长度适当的数组

states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states,years]).mean()

直接对DataFrame进行分组聚合

df.groupby(['key1']).mean()
第10章 数据聚合与分组运算_第5张图片
image.png

返回的结果中没有key2列,因为df['key2']不是数值列,所以被认为是‘麻烦列’,会在结果中自动滤除

返回各个分组大小的Series对象:groupby().size()

对分组进行迭代

for name,group in df.groupby(['key1','key2']):
    print(name)
    print('...seperator...')
    print(group)
第10章 数据聚合与分组运算_第6张图片
image.png

默认情况下分组是在0轴上进行的,也可以更改axis使之在1轴上传播。
如下,使得df根据每列的数据类型进行分组

第10章 数据聚合与分组运算_第7张图片
df

grouped=df.groupby(df.dtypes,axis=1)
for key,value in grouped:
    print(key)
    print(value)
df.dtypes
第10章 数据聚合与分组运算_第8张图片
image.png

选取一列或列的子集

通过字典或Series进行分组

传入字典,则可以在分组的同时,分配组名

mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
   ....:            'd': 'blue', 'e': 'red', 'f' : 'orange'}

by_column=people.groupby(mapping,axis=1)
In [62]: by_column.sum()
Out[62]:
            blue       red
Joe     2.640600  0.535645
Steve  -1.027999 -0.109327
Wes     1.114823  1.684028
Jim    -1.004846  2.967557
Travis -0.546900  1.540500

通过函数进行分组

被当作分组键的函数会对所有索引都调用一次

people.groupby(len).sum()

根据索引级别分组

10.2 数据聚合

常见聚合运算

第10章 数据聚合与分组运算_第9张图片
image.png

要使用自定义聚合函数只需将行数传入agg方法即可

grouped.agg(my_fun)

面向列的多函数应用

对于前面表的描述统计方法,可以函数名以字符串的形式传入(支持传入列表)

grouped_pct.agg(['mean','std'])

第10章 数据聚合与分组运算_第10张图片
image.png

这样使得自定义函数可以和自带的聚合函数混合使用
也可由给聚合函数添加名字:传递元组

grouped_pct.agg([('平均值','mean'),('标准差','std')])

更方便的写法

functions=[('平均值','mean'),('标准差','std')]
grouped_pct.agg(functions)

10.3 apply:一般性的“拆分-应用-合并

相比agg,agg只是对每个分组使用聚合运算,而app则是将分组中的每块DataFrame对象进行运算,因此更具一般性。

使用范例:

def top(df,n=5,column='tip_pct'):
    return df.sort_values(by=column)[-5:]
tips.groupby('day').apply(top)

groupby对象的apply方法:
groupby对象的每一块都是一个DataFrame对象,对其用apply就相当于将参数函数应用到每一个DataFrame块,因此要求参数函数也要能返回一个DataFrame对象。

apply和agg方法的区别:
agg方法是对一组数据执行的操作,而apply是对一块数据(DataFrame对象)执行的操作

ps:实际上对groupby对象调用describe方法等价于:

tips.groupby('day').apply(lambda x:x.describe())
第10章 数据聚合与分组运算_第11张图片
image.png

禁止分组键

使用参数:group_keys=Flase即可禁止分组键

tips.groupby('day',group_keys=False).apply(lambda x:x.describe())

分位数和桶分析

按数值区间分类
pd.cut
按个数区间分类
pd.qcut

示例1:对特定的分组填充不同的值

使用groupby+apply+填充函数

示例2: 随机采样和排列

创建一个德州扑克Series对象

suits=['H','S','C','D']
card_val=(list(range(1,11))+[10]*3)*4
base_names=['A']+list(range(2,11))+['J','K','Q']
for suit in suits:
    cards.extend(str(num)+suit for num in base_names)
In [139]: deck.head(10)
Out[139]:
AH      1
2H      2
3H      3
4H      4
5H      5
6H      6
7H      7
8H      8
9H      9
10H    10

使用sample随机选取5张扑克:

deck.sample(5)

从每种花色中随机抽取两张牌
分组标准:卡名的最后一个字母即花色。

def fun(se):
    return se.sample(2)
grouped=deck.groupby([x[-1] for x in deck.index])
grouped.apply(fun)

示例:分组加权平均数和相关系数

分组加权平均数
先分组,再对groupby对象调用average函数(可接收权重参数的mean)即可
分组相关系数
先分组,再对groupby对象调用corrwith

示例3:组级别的线性回归

10.4 透视表和交叉表

df.pivot_table:可以实现和groupby的相同功能,但简化了使用方式。
回到之前的消费的例子

In [254]: df.head(10)
Out[254]:
   total_bill   tip smoker  day    time  size   tip_pct
0       16.99  1.01     No  Sun  Dinner     2  0.059447
1       10.34  1.66     No  Sun  Dinner     3  0.160542
2       21.01  3.50     No  Sun  Dinner     3  0.166587
3       23.68  3.31     No  Sun  Dinner     2  0.139780
4       24.59  3.61     No  Sun  Dinner     4  0.146808
5       25.29  4.71     No  Sun  Dinner     4  0.186240
6        8.77  2.00     No  Sun  Dinner     2  0.228050
7       26.88  3.12     No  Sun  Dinner     4  0.116071
8       15.04  1.96     No  Sun  Dinner     2  0.130319
9       14.78  3.23     No  Sun  Dinner     2  0.218539
In [258]: df.pivot_table(['tip_pct','size'],index=['time','day'],columns='smoker')
Out[258]:
                 size             tip_pct
smoker             No       Yes        No       Yes
time   day
Dinner Fri   2.000000  2.222222  0.139622  0.165347
       Sat   2.555556  2.476190  0.158048  0.147906
       Sun   2.929825  2.578947  0.160113  0.187250
       Thur  2.000000       NaN  0.159744       NaN
Lunch  Fri   3.000000  1.833333  0.187735  0.188937
       Thur  2.500000  2.352941  0.160311  0.163863
第10章 数据聚合与分组运算_第12张图片
image.png

交叉表:crosstab

交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。

你可能感兴趣的:(第10章 数据聚合与分组运算)