- 对数据集进行分组并对各组应用一个函数(聚合或者转换),这是数据分析工作的一个重要环节
- 数据集准备好后,通常任务就是计算分组统计或生成透视表
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
1、根据一个或多个键拆分pandas对象
pandas
的groupby
可以对数据集进行切片、切块、摘要等
df=DataFrame({'key1':['a','a','b','b','a'],
'key2':['one','two','one','two','one'],
'data1':np.random.randn(5),
'data2':np.random.randn(5)})
访问data1
,并根据key1
调用groupby
grouped = df['data1'].groupby(df['key1'])
grouped
返回一个groupby
对象,它并没有进行任何计算,但该对象已经有了接下来对各分组执行运算所需的一切信息
grouped.mean()
## 返回一个含有分组大小的Series
df.groupby(['key1','key2']).size()
- 对分组进行迭代,可以产生一组二元元组(有分组名和数据块组成)
for name,group in df.groupby('key1'):
print (name)
print (group)
Out:
a
key1 key2 data1 data2
0 a one -0.315867 -2.518720
1 a two -0.510433 1.062739
4 a one -0.432449 0.320446
b
key1 key2 data1 data2
2 b one -1.382297 -0.034554
3 b two 2.742859 0.399418
for (k1,k2), group in df.groupby(['key1','key2']):
print(k1,k2)
print(group)
Out:
a one
key1 key2 data1 data2
0 a one -0.315867 -2.518720
4 a one -0.432449 0.320446
a two
key1 key2 data1 data2
1 a two -0.510433 1.062739
b one
key1 key2 data1 data2
2 b one -1.382297 -0.034554
b two
key1 key2 data1 data2
3 b two 2.742859 0.399418
- 选取一个或多个列
df.groupby(['key1','key2'])['data2'].mean()
得到Dataframe
形式的结果
df.groupby(['key1','key2'])[['data2']].mean()
- 通过字典或
Series
进行分组
people = DataFrame(np.random.randn(5,5),columns=['a','b','c','d','e'],index=['joe','steve','wes','jim','travis'])
people.loc[2:3,['b','c']]=np.nan
## 字典
mapping={'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
by_column = people.groupby(mapping,axis=1)
by_column.sum()
## series
map_series = Series(mapping)
people.groupby(map_series,axis=1).sum()
- 通过函数进行分组
通过人名的长度进行分组,只需要传入len
函数
people.groupby(len).sum()
- 根据索引级别分组
columnss = pd.MultiIndex.from_arrays([['us','us','us','jp','jp'],[1,3,5,1,3]],names=['cty','tenor'])
hier_df = DataFrame(np.random.randn(4,5),columns=columnss)
hier_df.groupby(level='cty',axis=1).count()
2、计算分组摘要统计
统计包括计数、平均值、标准差、或用户自定义函数
- 数据聚合
quantile
可以计算DataFrame
、Series
样本分位数
df
Out:
key1 key2 data1 data2
0 a one -1.216684 -0.116255
1 a two -1.264090 -1.455701
2 b one -0.241362 -0.732853
3 b two -0.234600 1.182641
4 a one -0.517819 0.840338
grouped = df.groupby('key1')
grouped['data1'].quantile(0.9)
自定义聚合函数
def peak_to_peak(arr):
return arr.max()-arr.min()
grouped.agg(peak_to_peak)
grouped.describe()
3、分组级运算和转
聚合是分组运算中的一种,是数据转换的一个特例
为一个Dataframe
添加一个用于存放各索引分组平均值的列
- 先聚合再合并
k1_means = df.groupby('key1').mean().add_prefix('mean_')
k1_means
Out:
mean_data1 mean_data2
key1
a -0.999531 -0.243873
b -0.237981 0.224894
pd.merge(df,k1_means,left_on='key1',right_index=True)
transform
方法
key = ['one','two','one','two','one']
people.groupby(key).mean()
people.groupby(key).transform(np.mean)
people
Out:
a b c d e
joe -0.115445 -0.084339 0.199401 0.972242 0.304742
steve -0.021287 -1.053292 1.441496 -0.606788 1.137274
wes -0.990943 NaN NaN 0.472071 0.361137
jim -0.332479 -0.492248 -0.298820 -1.039121 0.390657
travis -0.226006 -0.111077 0.553626 1.211031 0.934692
从各组减去平均值,该值会被广播出去,首先创建一个距平化函数
def demean(arr):
return arr-arr.mean()
demeaned = people.groupby(key).transform(demean)
4、用特定于分组的值填充缺失值
特定的值可以是平均值、中位数等等。
s=Series(np.random.randn(6))
s[::2]=np.nan
s.fillna(s.mean())
假设需要对不同对分组填充不同的值,美国的几个州的实力数据,这些州又被分为西部和中部
states = ['ohio','newyork','vermont','florida','oregon','nevada','california','idaho']
group_key = ['east']*4 +['west']*4
data = Series(np.random.randn(8),index=states)
- 第一种方法
data[['vermont','nevada','idaho']]=np.nan
data
Out:
ohio 0.118091
newyork -0.324106
vermont NaN
florida -0.208641
oregon -0.710107
nevada NaN
california 1.998600
idaho NaN
dtype: float64
data.groupby(group_key).mean()
fill_mean = lambda g:g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
- 第二种方法,运用
name
属性
fill_values = {'east':0.5,'west':-1}
fill_func = lambda g : g.fillna(fill_values[g.name])
data.groupby(group_key).apply(fill_func)