对数据集进行分组并对各组应用一个函数,这是数据分析的一个重要环节,将数据集准备好后,接下来的任务就是计算分组统计或深成透视表

GroupBy技术(分组)

创建一个GroupBy对象,再调用GroupBy的各种方法计算相关数据

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)})
grouped = df['data1'].groupby(df['key1'])	     #先访问data1,再根据key1调用groupby
(df.groupby(xxx))		#创建一个GroupBy对象
grouped.mean()
grouped.size()
# groupby的参数是分组的键,分组键可以是Series,也可以是任何长度适当的数组,也可以是DataFrame的列名
df.groupby(df['key1'])	
			#以Series为分组键
states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states, years]).mean()
			#以任何长度的数组为分组键
df.groupby('key1')
			#以DataFrame的列名为分组键
  1. 对分组(GroupBy对象)进行迭代
GroupBy支持迭代,返回的一组二元元组:分组名+数据块
>>>for name, group in df.groupby('key1'):
       print(name)
       print(group)
a
  key1 key2     data1     data2
0    a  one -1.676303 -0.424336
1    a  two  0.043207 -0.172227
4    a  one -0.165924 -0.145246
b
  key1 key2     data1     data2
2    b  one  1.449175  0.155494
3    b  two -0.379370 -0.075793
对数据片段做任何操作:将这些数据片段做成一个字典
pieces = dict(list(df.groupby('key1')))   #list既将刚刚打印的东西作为一个列表,dict是将打印的name作为key,将group作为value
  1. 选取一个或一组列
> 对于由DataFrame产生的GroupBy对象,如果用一个或一组列名对其进行索引,就能实现选取部分列进行聚合的目的
df.groupby(['key1', 'key2'])[['data2','data1']].mean()
			#以一个数组作为索引,返回的是DataFrame
df.groupby(['key1', 'key2'])['data2'].mean()
			#以单个列名作为索引,返回的是Series
  1. 通过Series或字典进行GroupBy
> 通过字典或Series给列名分组,然后再根据新分的组GroupBy
mapping = {'a': 'red', 'b': 'red', 'c': 'blue',
           'd': 'blue', 'e': 'red', 'f' : 'orange'}
by_column = people.groupby(mapping, axis=1)
by_column.sum()
map_series = pd.Series(mapping)
map_series
people.groupby(map_series, axis=1).count()   #以Series作为分组键
  1. 通过函数进行分组

函数作为分组键的传入,则该函数会在各个***索引值***上被调用一次,其返回值都会被用作分组名称

people.groupby(len).sum()		#按人名长度进行分组,直接传入函数名称,不用带(),也不用带参数
# 将函数和数组、列表、字典、Series混合使用也不是问题
key_list = ['one', 'one', 'one', 'two', 'two']
people.groupby([len, key_list]).sum()
  1. 根据索引级别分组
用level关键字传入级别编号,用axis=1对竖向GroupBy
hier_df.groupby(level='cty', axis=1).count()

数据聚合

# 直接使用groupby内含的方法
>>> grouped['data1'].quantile(0.9)
>>> grouped.describe()
# 使用自己的聚合函数,将函数名称传入aggregate或agg方法即可:
>>> def peak_to_peak(arr):
    	return arr.max() - arr.min()
>>> grouped.agg(peak_to_peak)
# 经过优化的GroupBy的方法
count		#分组中非NA值的数量
sum			#非NA值的和
mean 		#非NA值的平均数
median 		#非NA值的算术中位数
std\var		#无偏(分母n-1)标准差和方差
min\max		#非NA值的最小值和最大值
prod		#非NA值的积
first\last	#第一个和最后一个非NA值
  1. 面向列的多函数应用
    对不同的列使用不同的聚合函数,或一次应用多个函数
# 传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名
>>> grouped_pct.agg(['mean', 'std', peak_to_peak])
>>> grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])	
					#由(name, function)元组组成的列表作为参数传入,各元组的第一个元素会被用作DataFrame的列名
# 应用多个函数,将函数以列表形式传入
>>> functions = ['count', 'mean', 'max']
>>> result = grouped['tip_pct', 'total_bill'].agg(functions)
# 对不同的列应用不同的函数,向agg传入一个从列名映射到函数的字典
>>> grouped.agg({'tip_pct' : ['min', 'max', 'mean', 'std'], 'size' : 'sum'})
  1. 以“无索引”的形式返回聚合函数:分组键不作为索引
grouped = tips.groupby(['day', 'smoker'], as_index=False)		#day和smoker不作为返回的dataframe的索引

分组级运算和转换

聚合知识分组运算的一种而已,它接受能够将一维数组简化为标量值的函数。
将介绍transform和apply方法,能够执行更多其他的分组运算