Python的数据聚合与分组运算

在进行数据分析的过程中往往需要我们对数据进行分类或合并,在本节将学习有关Python中的有关分组聚合的方法。

0 分组聚合原理

在Pandas中,分组是指使用特定的条件将原数据划分为多个组,聚合在这里指的是,对每个分组中的数据执行某些操作,最后将计算的结果进行整合。

参考文档:Group By: split-apply-combine

分组聚合原理

1 groupby方法

1.1 语法

1
groupby(by=None, axis=0, level=None, as_index=True, sort=True,group_keys=True, squeeze=False, observed=False, **kwargs)
  • by:用于确定进行分组的依据

  • axis:表示分组轴的方向

  • sort:表示是否对分组标签进行排序,接收布尔值,默认为True

by参数可接收的数据主要有:列表或数组DataFrame某列字典或Series对象函数

1.2 实例

1.2.1 按照Key进行分组,使用列索引字段
1
2
3
4
5
6
7
8
9
import pandas as pd
data = pd.DataFrame({
"Key": ['C', 'B', 'C', 'A', 'B', 'B', 'A', 'C', 'A'],
"Data": [2, 4, 6, 8, 10, 1, 14, 16, 18]
})

data_obj = data.groupby(by="Key")
for i in data_obj:
print(i)

输出

1
2
3
4
5
6
7
8
9
10
11
12
('A',   Key  Data
3 A 8
6 A 14
8 A 18)
('B', Key Data
1 B 4
4 B 10
5 B 1)
('C', Key Data
0 C 2
2 C 6
7 C 16)

可以看出,程序通过关键词Key将数据分为三组:

数据分组示意图

1.2.2 使用series进行分组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pandas as pd
data = pd.DataFrame({
"Key": ['C', 'B', 'C', 'A', 'B', 'B', 'A', 'C', 'A'],
"Data": [2, 4, 6, 8, 10, 1, 14, 16, 18]
})
ser_obj = pd.Series([
'a',
'b',
'c',
'a',
'b',
'c',
'a',
'b',
'c',
])
group_obj = data.groupby(by=ser_obj)
for i in group_obj:
print(i)

输出

1
2
3
4
5
6
7
8
9
10
11
12
('a',   Key  Data
0 C 2
3 A 8
6 A 14)
('b', Key Data
1 B 4
4 B 10
7 C 16)
('c', Key Data
2 C 6
5 B 1
8 A 18)

通过Series对象来分组可以理解成在原DataFrame数据中添加了一列数据,分组时以该列数据作为key进行索引分组。如果Series对象的索引长度大于或小于源数据,不会报错只会输出交集部分。

1.2.3 通过字典进行分组
1
2
3
4
5
6
7
8
9
10
import pandas as pd
data = pd.DataFrame({
'A': [1, 2, 3, 4, 5],
'B': [6, 7, 8, 9, 10],
'C': [11, 12, 13, 14, 15]
})
mapping = {'A': '第一组', 'B': '第一组', 'C': '第二组'}
by_dict = data.groupby(mapping, axis=1)
for i in by_dict:
print(i)

输出

1
2
3
4
5
6
7
8
9
10
11
12
('第一组',    A   B
0 1 6
1 2 7
2 3 8
3 4 9
4 5 10)
('第二组', C
0 11
1 12
2 13
3 14
4 15)

可以发现A,B已经放入了第一组,而C放入了第二组,注意组中只会包括字典中的元素,例如:

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
data = pd.DataFrame({
'A': [1, 2, 3, 4, 5],
'B': [6, 7, 8, 9, 10],
'C': [11, 12, 13, 14, 15],
'D': [16, 17, 18, 19, 20]
})
mapping = {'A': '第一组', 'B': '第一组', 'C': '第二组'}
by_dict = data.groupby(mapping, axis=1)
for i in by_dict:
print(i)

输出:

1
2
3
4
5
6
7
8
9
10
11
12
('第一组',    A   B
0 1 6
1 2 7
2 3 8
3 4 9
4 5 10)
('第二组', C
0 11
1 12
2 13
3 14
4 15)
1.2.4 通过函数分组
1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
data = pd.DataFrame(
{
'A': [1, 2, 3, 4, 5],
'B': [6, 7, 8, 9, 10],
'C': [11, 12, 13, 14, 15],
'D': [16, 17, 18, 19, 20]
},
index=['zz', 'yxy', 'wcc', 'ln', 'wyf'])
fun_obj = data.groupby(len)
for i in fun_obj:
print(i)

输出

1
2
3
4
5
6
7
(2,     A  B   C   D
zz 1 6 11 16
ln 4 9 14 19)
(3, A B C D
yxy 2 7 12 17
wcc 3 8 13 18
wyf 5 10 15 20)

通过长度函数len对数据进行分组

2 数据聚合

数据聚合,一般是指对分组中的数据执行某些操作,例如平均值、最大值,操作之后会得到一个结果集,这些实现聚合的操作称为聚合方法。

2.1 内置的统计方法聚合数据

例如我们对下表数据按key1分组后求每个分组的平均值:

key1 key2 data1 data2
0 A one 2 3.0
1 A two 3 5.0
2 B one 4 NaN
3 B two 6 3.0
4 A one 8 7.0
2.1.1 实例代码
1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
data = pd.DataFrame({
'key1': ['A', 'A', 'B', 'B', 'A'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': [2, 3, 4, 6, 8],
'data2': [3, 5, np.nan, 3, 7]
})
print(data.groupby('key1').mean())
2.1.2 输出
1
2
3
4
         data1  data2
key1
A 4.333333 5.0
B 5.000000 3.0

如果原数据为:

1
2
3
4
5
6
data = pd.DataFrame({
'key1': ['A', 'A', 'B', 'B', 'A'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': [2, 3, np.nan, np.nan, 8],
'data2': [3, 5, np.nan, np.nan, 7]
})

则输出为:

1
2
3
4
         data1  data2
key1
A 4.333333 5.0
B NaN NaN

可知如果参与运算的数据中有NaN值则会自动过滤这些NaN值。

2.2 面向列的聚合方法

当内置的方法无法满足需求时可以自定义一个函数传给agg()方法实现对SeriesDataFrame对象进行聚合运算。

2.2.1 agg()函数
语法
1
agg(func,axis=0,*args,**kwargs)
  • func:表示用于汇总数据的函数,可以为单个函数或函数列表
  • axis:表示函数作用于轴的方向
对每一列数据应用同一函数

通过对表格中的key值进行分组,计算每个分组中每列数据的和

表格

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
# 创建表格
data = pd.DataFrame(np.arange(36).reshape(6,6),columns=list('abcdef'))
data['key'] = pd.Series(list('aaabbb'))
# 通过key分组
data_gr = data.groupby(by='key')
# 对每列求和
print(data_gr.agg(sum))

输出

1
2
3
4
      a   b   c   d   e   f
key
a 18 21 24 27 30 33
b 72 75 78 81 84 87

拓展:

可以通过:

1
print(dict([x for x in data_gr])['a'])

获取a组的数据:

1
2
3
4
    a   b   c   d   e   f key
0 0 1 2 3 4 5 a
1 6 7 8 9 10 11 a
2 12 13 14 15 16 17 a
拓展:

通过agg()使用自定义函数

在下述代码中将定义一个求每个分组数据的极差值的函数(最大值-最小值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np


def range_data_group(arr):
return arr.max() - arr.min()


# 创建表格
data = pd.DataFrame(np.arange(36).reshape(6, 6), columns=list('abcdef'))
data['key'] = pd.Series(list('aaabbb'))
# 通过key分组
data_gr = data.groupby(by='key')
print(data_gr.agg(range_data_group))

输出:

1
2
3
4
      a   b   c   d   e   f
key
a 12 12 12 12 12 12
b 12 12 12 12 12 12

本文标题:Python的数据聚合与分组运算

文章作者:小哲

发布时间:2020年05月09日 - 14:42

最后更新:2020年05月13日 - 18:36

原始链接: 点击复制原始链接

许可协议: 协议-转载请保留原文链接及作者