关于分组,我们可以借鉴下图来说明其原理(一张图胜过千言万语):
分组对象
pandas关于一个DataFrame或者Series的分组可以抽象为一个对象,在此基础之上我们可以使用不同的聚合函数来操作:
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)})
data1 | data2 | key1 | key2 | |
---|---|---|---|---|
0 | -0.754853 | -0.590699 | a | one |
1 | 1.753281 | 0.464985 | a | two |
2 | 0.953007 | -0.405809 | b | one |
3 | 0.637040 | -1.163453 | b | two |
4 | 0.497621 | -0.794294 | a | one |
# DataFrame和Series都可以分组
grouped = df['data1'].groupby(df['key1']) # 或者可以用 df['data1'].groupby(['key1'])
grouped.mean()
key1
a 0.498683
b 0.795023
Name: data1, dtype: float64
当然,可以两个键来对数据分组:
grouped = df['data1'].groupby([df['key1'], df['key2']])
grouped.mean()
key1 key2
a one -0.128616
two 1.753281
b one 0.953007
two 0.637040
Name: data1, dtype: float64
分组的其它操作
其它操作例如对组进行迭代,通过字典分组,通过函数分组等,在此不做详细解释,详细参考利用python进行数据分析。
分组运算
1. 聚合aggregation
除了mean(),min()等pandas内部已经构造好的聚合函数,我们可以使用函数agg来使用自定的聚合函数:
grouped = df['data1'].groupby(df['key1'])
def peak_to_peak(arr):
return arr.max() - arr.min()
grouped.agg(peak_to_peak)
key1
a 2.508134
b 0.315966
Name: data1, dtype: float64
多个字段的聚合要用到字典作为agg的参数:
grouped = df.groupby(df['key1'])
grouped.agg({'data1':'mean', 'data2': 'max'})
2. 数据转化 transformation
聚合只是分组运算当中的一种而已,说白了,它只接受将一维数组投射为一个标量的函数。实际操作当,我们往往需要另外的分组运算, 比如说我们需要将分组的聚合运算结果分配到原分组的每个元素上,换句话说,一维数组聚合运算后得到的一个标量需要再分配个原一维数组的每个元素上(不容易表达,看代码秒懂):
df.groupby('key1').transform('mean')
data1 data2 0 -0.472175 0.193949 1 -0.472175 0.193949 2 -0.100747 0.682257 3 -0.100747 0.682257 4 -0.472175 0.193949
可以看到key1为 'a' 的记录其对应的 data1 以及 data2 列的元素值是相同的,皆为key1为'1'的分组的对应平均值。
3. apply
groupby和transform,一个是把一维数组投射于标量,一个是一维数组仍然映射到相同维度的一维数组。这些都是比较固定的用法,而apply是一种灵活的分组运算,可以多对一,可以多对多,也可以多对一部分!
# 返回前n行
def first_n(df, n=1):
return df[0:n]
print (df.groupby('key1').apply(first_n, n=1))
data1 data2 key1 key2 key1 a 0 0.728854 0.143157 a one b 2 1.070968 -1.240389 b one
print (df.groupby('key1').apply(first_n, n=2))
data1 data2 key1 key2 key1 a 0 0.728854 0.143157 a one 1 -0.412097 0.920794 a two b 2 1.070968 -1.240389 b one 3 0.957364 0.803426 b two
函数first_n可以返回分组的前n行,以上可以看到效果。
参考文献:
[1] 利用Python进行数据分析
[2] Pandas groupby apply agg 区别 运行自定义函数