对数据集进行分组并对各组应用一个函数(无论是聚合还是转换),这是数据分析工作中的重要环节。在将数据集准备好之后,通常的任务就是计算分组统计或生成透视表。pandas提供了一个灵活高效的groupby功能,它使你能以以一种自然的方式对数据集进行切片、切块、摘要等操作。
一、GroupBy技术
“split-apply-combine”(拆分-应用-合并),很好的描述了分组运算的整个过程,如下图所示。
- 第一阶段:pandas对象中的数据会根据你所提供的一个或多个键被拆分(split)为多组。拆分操作是在对象的特定轴上执行的。
- 第二阶段:将一个函数应用(apply)到各个分组并产生一个新值。
- 第三阶段:所有这些函数的执行结果会被合并(combine)到最终的结果对象中。
1.1 group by基本用法
代码示例:
import numpy as np
import pandas as pd
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
#分组键是Series对象
grouped = df['data1'].groupby(df['key1']) #返回GroupBy对象,并未计算,但包含计算的所有信息
grouped.mean()
means = df['data1'].groupby([df['key1'], df['key2']]).mean()
"""
df: grouped.mean(): means:
data1 data2 key1 key2 key1 key1 key2
0 -0.092273 -0.658181 a one a 0.370973 a one -0.188932
1 1.490783 -0.601443 a two b 0.422070 two 1.490783
2 0.657373 -1.449184 b one b one 0.657373
3 0.186767 1.233480 b two two 0.186767
4 -0.285591 -0.234298 a one
"""
#分组键可以为任何适当长度的数组
states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()
"""result:
California 2005 -0.038644
2006 0.169926
Ohio 2005 0.702394
2006 -1.049059
"""
#分组还可以是列名(字符串、数字或其他python对象)
df.groupby('key1').mean()
"""
data1 data2
key1
a -0.010345 0.105864
b 0.259023 -0.230571
"""
df.groupby(['key1', 'key2']).mean()
"""
data1 data2
key1 key2
a one 0.003805 -0.103989
two -0.038644 0.525572
b one 0.169926 -0.459576
two 0.348119 -0.001566
"""
#groupby的size方法,返回的是一个含有分组大小的Series
df.groupby(['key1', 'key2']).size()
"""
df: df.groupby(['key1', 'key2']).size():
data1 data2 key1 key2 key1 key2
0 1.056668 -0.174590 a one a one 2
1 -0.038644 0.525572 a two two 1
2 0.169926 -0.459576 b one b one 1
3 0.348119 -0.001566 b two two 1
4 -1.049059 -0.033389 a one
"""
1.2 对分组进行迭代
GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)。
代码示例:
#Groupby对象支持迭代
import numpy as np
import pandas as pd
df = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
'key2' : ['one', 'two', 'one', 'two', 'one'],
'data1' : np.random.randn(5),
'data2' : np.random.randn(5)})
for name, group in df.groupby(