本系列文章配套代码获取有以下三种途径:
-
可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):
https://returu.github.io/Python_Data_Analysis/lab/index.html
-
也可以通过百度网盘获取,需要在本地配置代码运行环境,环境配置可以查看【Python基础】2.搭建Python开发环境:
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj
提取码:mnsj
-
前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis
根据《Python for Data Analysis 3rd Edition》翻译整理
—————————————————–
前面介绍了分组操作中的apply
方法,用于执行转换。还有一个内置的方法叫做transform
,它与apply
类似,但对可以使用的函数种类施加了更多限制:
-
它可以产生一个标量值,并广播到各分组的尺寸数据中;
-
它可以产生一个与输入分组尺寸相同的对象;
-
它不得改变其输入。
agg
、apply
和transform
三个方法的输入对象都是分组后的DataFrame/Series,区别在于,他们的输出类型不一样:
-
agg
输出的是缩减后的标量(或者标量列表); -
transform
输出与原输入的DataFrame大小一致,但是数据元素是经过了转换的DataFrame; -
apply
比较灵活,它既可以是缩减后的标量,也可以是pandas对象。
首先构造一个示例DataFrame数据:
1>>> df = pd.DataFrame({'key': ['x', 'y', 'z', 'x', 'y', 'z', 'x', 'y', 'z', 'x', 'y', 'z'],
2... 'value1': np.arange(12), 'value2': np.arange(12,24)},
3... index=['a','b','c','d','e','f','g','h','i','j','k','l'])
4
5>>> df
6 key value1 value2
7a x 0 12
8b y 1 13
9c z 2 14
10d x 3 15
11e y 4 16
12f z 5 17
13g x 6 18
14h y 7 19
15i z 8 20
16j x 9 21
17k y 10 22
18l z 11 23
然后按key
列进行分组操作:
1>>> grouped = df.groupby('key')
2>>> for name , value in grouped:
3... print(name)
4... print(value)
5
6x
7 key value1 value2
8a x 0 12
9d x 3 15
10g x 6 18
11j x 9 21
12y
13 key value1 value2
14b y 1 13
15e y 4 16
16h y 7 19
17k y 10 22
18z
19 key value1 value2
20c z 2 14
21f z 5 17
22i z 8 20
23l z 11 23
假设,需要根据分组计算平均值,可以使用内置的聚合函数mean
。
可以看出,agg
和apply
会对数据进行聚合,而transform
则不会(则会将值替换为分组的平均值)。
1>>> grouped.agg("mean")
2 value1 value2
3key
4x 4.5 16.5
5y 5.5 17.5
6z 6.5 18.5
7
8
9>>> grouped.apply("mean")
10 value1 value2
11key
12x 4.5 16.5
13y 5.5 17.5
14z 6.5 18.5
15
16
17>>> grouped.transform("mean")
18 value1 value2
19a 4.5 16.5
20b 5.5 17.5
21c 6.5 18.5
22d 4.5 16.5
23e 5.5 17.5
24f 6.5 18.5
25g 4.5 16.5
26h 5.5 17.5
27i 6.5 18.5
28j 4.5 16.5
29k 5.5 17.5
30l 6.5 18.5
transform
适用于返回 Series 的函数,但结果必须与输入的大小相同。例如,我们可以使用自定义函数将每个组乘以 2。
1>>> def time_two(group):
2... return group * 2
3
4
5>>> grouped.apply(time_two)
6 key value1 value2
7a xx 0 24
8b yy 2 26
9c zz 4 28
10d xx 6 30
11e yy 8 32
12f zz 10 34
13g xx 12 36
14h yy 14 38
15i zz 16 40
16j xx 18 42
17k yy 20 44
18l zz 22 46
19
20
21>>> grouped.transform(time_two)
22 value1 value2
23a 0 24
24b 2 26
25c 4 28
26d 6 30
27e 8 32
28f 10 34
29g 12 36
30h 14 38
31i 16 40
32j 18 42
33k 20 44
34l 22 46
不同的是,apply
允许对dataframe的多个series进行操作,而 transform
则会报错。
1>>> def sum_func(group):
2... return (group["value1"] + group["value2"])
3
4
5>>> df.groupby('key').apply(sum_func)
6key
7x a 12
8 d 18
9 g 24
10 j 30
11y b 14
12 e 20
13 h 26
14 k 32
15z c 16
16 f 22
17 i 28
18 l 34
19dtype: int32
20
21
22>>> df.groupby('key').transform(sum_func)
23KeyError: 'value1'
需要注意的是,虽说apply拥有更大的灵活性,但apply
的运行效率会比agg
和transform
慢。因此,groupby
之后优先使用agg
和transform
解决问题还,如若不行才考虑使用apply
。
本篇文章来源于微信公众号: 码农设计师