Pandas库中的transform函数怎样用?
Admin 2021-09-24 群英技术资讯 722 次浏览
今天给大家分享的是Pandas库中的transform函数,我们知道Pandas库有很多很强大的功能,接下来来给大家介绍的transform函数就是其中之一,使用transform函数,我们可以实现高效的汇总数据且不改变数据行数,接下来我们就来详细的了解一下transform函数。
Pandas函数的核心功能是,既计算了统计值,又保留了明细数据。为了更好地理解transform和agg的不同,下面从实际的应用场景出发进行对比。
aggregation会返回数据的缩减版本,而transformation能返回完整数据的某一变换版本供我们重组。这样的transformation,输出的形状和输入一致。一个常见的例子是通过减去分组平均值来居中数据。
#数据构造 data = pd.DataFrame( {"company":['百度', '阿里', '百度', '阿里', '百度', '腾讯', '腾讯', '阿里', '腾讯', '阿里'], "salary":[43000, 24000, 40000, 39000, 8000, 47000, 25000, 16000, 21000, 38000], "age":[25, 34, 49, 42, 28, 23, 45, 21, 34, 29]}) data company salary age 0 百度 43000 25 1 阿里 24000 34 2 百度 40000 49 3 阿里 39000 42 4 百度 8000 28 5 腾讯 47000 23 6 腾讯 25000 45 7 阿里 16000 21 8 腾讯 21000 34 9 阿里 38000 29
当transform作用于单列Series时较为简单 ,对salary列进行transform变换我们可以传入任意的非聚合类函数,比如对工资列对数化
import pandas as pd import numpy as np # 对工资对数化 data['salary'].transform(np.log) 0 10.668955 1 10.085809 2 10.596635 3 10.571317 4 8.987197 5 10.757903 6 10.126631 7 9.680344 8 9.952278 9 10.545341 Name: salary, dtype: float64
除了内置函数,还可以传入lambda函数
# lambda函数 data['salary'].transform(lambda s: s+1) 0 43001 1 24001 2 40001 3 39001 4 8001 5 47001 6 25001 7 16001 8 21001 9 38001 Name: salary, dtype: int64
也可以传入包含多个变换函数的列表来一口气计算出多列结果:
data['salary'].transform([np.log, lambda s: s+1, np.sqrt]) log <lambda> sqrt 0 10.668955 43001 207.364414 1 10.085809 24001 154.919334 2 10.596635 40001 200.000000 3 10.571317 39001 197.484177 4 8.987197 8001 89.442719 5 10.757903 47001 216.794834 6 10.126631 25001 158.113883 7 9.680344 16001 126.491106 8 9.952278 21001 144.913767 9 10.545341 38001 194.935887
而又因为transform传入的函数,在执行运算时接收的输入参数是对应的整列数据,所以我们可以利用这个特点实现诸如数据标准化、归一化等需要依赖样本整体统计特征的变换过程:
# 利用transform进行数据标准化 data['salary'].transform(lambda s: (s - s.mean()) / s.std()) 0 0.991038 1 -0.468630 2 0.760564 3 0.683739 4 -1.697825 5 1.298337 6 -0.391806 7 -1.083228 8 -0.699104 9 0.606915 Name: salary, dtype: float64
当transform作用于整个DataFrame时,实际上就是将传入的所有变换函数作用到每一列中:
data.loc[:,'salary':'age'].transform(lambda s:(s-s.mean()) /s.std()) salary age 0 0.991038 -0.832050 1 -0.468630 0.104006 2 0.760564 1.664101 3 0.683739 0.936057 4 -1.697825 -0.520031 5 1.298337 -1.040063 6 -0.391806 1.248075 7 -1.083228 -1.248075 8 -0.699104 0.104006 9 0.606915 -0.416025
而当传入多个变换函数时,对应的返回结果格式类似agg中的机制,会生成MultiIndex格式的字段名
data.loc[:, 'salary': 'age'].transform([np.log, lambda s: s+1]) salary age log <lambda> log <lambda> 0 10.668955 43001 3.218876 26 1 10.085809 24001 3.526361 35 2 10.596635 40001 3.891820 50 3 10.571317 39001 3.737670 43 4 8.987197 8001 3.332205 29 5 10.757903 47001 3.135494 24 6 10.126631 25001 3.806662 46 7 9.680344 16001 3.044522 22 8 9.952278 21001 3.526361 35 9 10.545341 38001 3.367296 30
而且由于作用的是DataFrame,还可以利用字典以键值对的形式,一口气为每一列配置单个或多个变换函数:
(data.loc[:, 'salary': 'age'] .transform({'age': lambda s: (s - s.mean()) / s.std(), 'salary': [np.log, np.sqrt]})) age salary <lambda> log sqrt 0 -0.832050 10.668955 207.364414 1 0.104006 10.085809 154.919334 2 1.664101 10.596635 200.000000 3 0.936057 10.571317 197.484177 4 -0.520031 8.987197 89.442719 5 -1.040063 10.757903 216.794834 6 1.248075 10.126631 158.113883 7 -1.248075 9.680344 126.491106 8 0.104006 9.952278 144.913767 9 -0.416025 10.545341 194.935887
在原来的数据中,我们知道了如何求不同公司的平均薪水,假如需要在原数据集中新增一列salary_mean,代表该公司的平均薪水,该怎么实现呢?
data['salary_mean'] = data.groupby('company')[['salary']].transform('mean') data company salary age salary_mean 0 百度 43000 25 30333.333333 1 阿里 24000 34 29250.000000 2 百度 40000 49 30333.333333 3 阿里 39000 42 29250.000000 4 百度 8000 28 30333.333333 5 腾讯 47000 23 31000.000000 6 腾讯 25000 45 31000.000000 7 阿里 16000 21 29250.000000 8 腾讯 21000 34 31000.000000 9 阿里 38000 29 29250.000000
通过上面的数据可以看出,利用transform输出既得到了统计数据,形状也没有变化。
当然,也可对多个数据列进行计算
data.groupby('company')[['salary', 'age']].transform('mean') salary age 0 30333.333333 34.0 1 29250.000000 31.5 2 30333.333333 34.0 3 29250.000000 31.5 4 30333.333333 34.0 5 31000.000000 34.0 6 31000.000000 34.0 7 29250.000000 31.5 8 31000.000000 34.0 9 29250.000000 31.5
我们也可以用map函数实现类似的功能,但是稍微复杂点,但是有助于我们理解transform的含义。
avg_dict = data.groupby('company')['salary'].mean().to_dict() avg_dict#得到了一个平均工资的字典 {'百度': 30333.333333333332, '腾讯': 31000.0, '阿里': 29250.0} #利用map函数,将得到的字典映射到对应的列 data['salary_mean'] = data['company'].map(avg_dict) data company salary age salary_mean 0 百度 43000 25 30333.333333 1 阿里 24000 34 29250.000000 2 百度 40000 49 30333.333333 3 阿里 39000 42 29250.000000 4 百度 8000 28 30333.333333 5 腾讯 47000 23 31000.000000 6 腾讯 25000 45 31000.000000 7 阿里 16000 21 29250.000000 8 腾讯 21000 34 31000.000000 9 阿里 38000 29 29250.000000
以图解的方式来看看进行groupby后transform的实现过程(公司列包含ABC,salary列为每个员工的工资明细):
上图中的大方框是transform和agg 所不一样的地方,对agg而言,会计算并聚合得到 A,B,C 公司对应的均值并直接返回,每个公司一条数据,但对transform而言,则会对每一条数据求得相应的结果,同一组内的样本会有相同的值,组内求完均值后会按照原索引的顺序返回结果。
关于Pandas库中的transform函数就介绍到这了,上述示例代码有一定的借鉴价值,需要的朋友可以参考。想要了解更多transform函数的内容,请浏览其他相关的文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
折线图在很多图标中都有使用,本文主要介绍了Python pyecharts Line折线图的具体实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
这篇文章介绍了Python中的文件系统模块pathlib库,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要介绍了Python中的简写操作(for、if简写、匿名函数),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
场景这两个功能一般不太常用。所能想到的场景大概也就是在几个页面间来回跳转,省去每次都geturl。代码#!/usr/bin/envpython#-*-coding:utf-8-*-'''Createdon2018/5/911:26@author:JeffLee@file:前进和后退.py'''fromseleniumimportwebdriver
内容介绍一、整理数据二、修改点的样式三、呈现半透明的状态四、点呈现多彩的颜色五、让点的大小不一六、侧边呈现颜色卡七、改变集中性一、整理数据importpandasaspdcnbodf=pd.r
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008