《Python for Data Analysis》
GroupBy
分组运算:split-apply-combine(拆分-应用-合并)
DataFrame可以在其行(axis=0)或列(axis=1)上进行分组。然后,将一个函数应用到各个分组并产生新值。最后,所有这些函数的执行结果会被合并到最终的结果对象中去。
GroupBy的size方法可以返回一个含有分组大小的Series。
- 对分组进行迭代
for (k1,k2), group in df.groupby(['key1','key2']):
print k1,k2
print group
- 选取一个或一组列
df.groupby(['key1','key2'])[['data2']].mean()
- 通过字典或Series进行分组
只需将字典或Series传给groupby即可。
- 通过函数分组
people.groupby(len).sum()
#根据人名的长度进行分组
- 通过索引级别分组
层次化索引数据,根据索引级别进行聚合,通过level关键字传入级别编号或名称。 df.groupby(level='cty',axis=1).count()
数据聚合
经过优化的groupby方法
函数名 | 说明 |
---|---|
count | 分组中非NA值得数量 |
sum | 非NA值的和 |
mean | 非NA值的平均值 |
median | 非NA值的算术平均数 |
std、var | 无偏(分母为n-1)标准差和方差 |
min、max | 非NA值的最小值和最大值 |
prod | 非NA值的积 |
first、last | 第一个和最后一个非NA值 |
对于上述描述统计方法,可以将函数名以字符串的形式传入agg方法。例如:grouped.agg(['mean', 'std'])
如果要使用自己的聚合函数,只需将其传入aggregate或agg方法即可
def peak_to_peak(arr):
return arr.max() - arr.min()
grouped.agg(peak_to_peak)
面向列的多函数应用,可以对不同的列使用不同的聚合函数或者一次应用多个函数。
- 如果传入一组函数或函数名,得到的DataFrame的列就会以相应的函数命名
- 如果传入的是一个由(name,function)元组组成的列表,各个元组的第一个元素就会被用作DataFrame的列名。
- 不同的列使用不同的聚合函数也可以向agg传入一个从列名映射到函数的字典
grouped.agg(['mean', 'std', peak_to_peak]) # 1
grouped.agg([('foo', 'mean'), ('bar', np.std)]) # 2
functions = ['count', 'mean', 'max']
result = grouped['tip', 'bill'].agg(functions) # 3
grouped.agg({'tip' : np.max, 'bill' : 'sum'}) # 4
分组级运算和转换
transform
transform会将一个函数应用到各个分组,然后将结果放置到适当的位置上。如果各个分组产生的是一个标量值,则该值就会被广播出去。
apply
一般性的“拆分-应用-合并”
tips.groupby('smoker').apply(top)
相当于top函数在DataFrame的各个片段上调用,然后结果由pandas.concat组装到一起,并以分组名称进行了标记。,于是,最终结果就有了一个层次化索引,其内层索引值来自于原DataFrame.
禁止分组键: 分组键会跟原始对象的索引共同构成结果对象中的层次化索引。将group_keys=False
传入groupby
即可禁止该效果。tips.groupby('smoker', group_keys=False).apply(top)
在GroupBy对象上调用describe
相当于f = lambda x : x.describe(); grouped.apply(f)
.