本文主要介绍Pandas统计函数:groupby、pivot_table及crosstab
产生数据
import numpy as np
import pandas as pd
from pandas import DataFrame
df = DataFrame({'key1':['a','a','b','b','a'],
'key2':['one','two','one','two','one'],
'data1':[1,2,3,2,5],
'data2':np.random.randn(5)})
print(df)
# data1 data2 key1 key2
# 0 1 0.493919 a one
# 1 2 -0.887280 a two
# 2 3 -0.267727 b one
# 3 2 0.048972 b two
# 4 5 0.309441 a one
分组groupby
Pandas中最为常用和有效的分组函数。
- 按列分组
注意以下使用groupby()函数生成的group1是一个中间分组变量,为GroupBy类型。既可依据单个列名’key1’进行为分组,也可依据多个列名[‘key1’,’key2’]进x行分组。根据for循环遍历元素。
# 根据单个列分组
group1 = df.groupby('key1')
print(group1)
# <pandas.core.groupby.DataFrameGroupBy object at 0x0000015036489710>
# 根据多个列分组
group2 = df.groupby(['key1','key2'])
print(group2)
# <pandas.core.groupby.DataFrameGroupBy object at 0x000001503636C080>
# 遍历group1中的元素
l=[x for x in group1]
print(l)
# [('a', data1 data2 key1 key2
# 0 1 0.493919 a one
# 1 2 -0.887280 a two
# 4 5 0.309441 a one),
# ('b', data1 data2 key1 key2
# 2 3 -0.267727 b one
# 3 2 0.048972 b two)]
- 按分组统计
在分组group1、group2上应用size()、sum()、count()等统计函数,能分别统计分组数量、不同列的分组和、不同列的分组数量。
# 调用聚合函数打印出每个组中结果
print(group1.size())
# key1
# a 3
# b 2
# dtype: int64
print(group1.sum() )
# data1 data2
# key1
# a 8 -0.083919
# b 5 -0.218755
print(group1.count())
# data1 data2 key2
# key1
# a 3 3 3
# b 2 2 2
- 应用agg()
对于分组的某一列或者多个列,应用agg(func)可以对分组后的数据应用func函数。例如:用group1[‘data1’].agg(‘mean’)对分组后的’data1’列求均值。当然也可以推广到同时作用于多个列和使用多个函数上。
print(group1['data1'].agg('mean'))
# key1
# a 2.666667
# b 2.500000
# Name: data1, dtype: float64
print(group1['data1'].agg(['mean','sum']))
# mean sum
# key1
# a 2.666667 8
# b 2.500000 5
print(group1['data1','data2'].agg(['mean','sum']))
# data1 data2
# mean sum mean sum
# key1
# a 2.666667 8 -0.556335 -1.669005
# b 2.500000 5 0.052789 0.105577
- 应用apply()
apply()不同于agg()的地方在于:前者应用于dataframe的各个列,后者仅作用于指定的列。
print(df.groupby('key1').apply(np.mean))
# data1 data2
# key1
# a 2.666667 0.083070
# b 2.500000 -0.346864
print(df.groupby(['key1','key2']).apply(np.mean))
# data1 data2
# key1 key2
# a one 3.0 0.556917
# two 2.0 -0.864626
# b one 3.0 0.723882
# two 2.0 -1.417610
透视表pivot_table
可以产生类似于excel数据透视表的结果,相当的直观。
- 分组统计
其中参数index指定“行”键,columns指定“列”键。
print(pd.pivot_table(df, index='key1', columns='key2'))
# data1 data2
# key2 one two one two
# key1
# a 3 2 0.246833 1.018249
# b 3 2 -0.508228 1.298586
print(df.pivot_table(['data1'], index='key1',columns='key2'))
# data1
# key2 one two
# key1
# a 3 2
# b 3 2
- 分项汇总
如果将参数margins设置为True,则可以得到分项总计数据。
print(df.pivot_table(index='key1',columns='key2', margins=True))
# data1 data2
# key2 one two All one two All
# key1
# a 3.0 2.0 2.666667 0.246833 1.018249 0.503971
# b 3.0 2.0 2.500000 -0.508228 1.298586 0.395179
# All 3.0 2.0 2.600000 -0.004854 1.158417 0.460454
交叉表crosstab
可以按照指定的行和列统计分组频数,用起来非常方便;当然同样的功能也可采用groupby实现。
print(pd.crosstab(df.key1,df.key2, margins=True))
# key2 one two All
# key1
# a 2 1 3
# b 1 1 2
# All 3 2 5