分享Pandas库中的一些宝藏函数transform()
Pandas函数的核心功能是,既计算了统计值,又保留了明细数据。为了更好地理解transform和agg的不同,下面从实际的应用场景出发进行对比。
aggregation会返回数据的缩减版本,而transformation能返回完整数据的某一变换版本供我们重组。这样的transformation,输出的形状和输入一致。一个常见的例子是通过减去分组平均值来居中数据。
#数据构造data = https://www.it610.com/article/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]}) datacompanysalaryage0百度43000251阿里24000342百度40000493阿里39000424百度8000285腾讯47000236腾讯25000457阿里16000218腾讯21000349阿里3800029
1、transform作用于Series 1)单个变换函数
当transform作用于单列Series时较为简单 ,对salary列进行transform变换我们可以传入任意的非聚合类函数,比如对工资列对数化
import pandas as pd import numpyas np# 对工资对数化data['salary'].transform(np.log) 010.668955110.085809210.596635310.57131748.987197510.757903610.12663179.68034489.952278910.545341Name: salary, dtype: float64
除了内置函数,还可以传入lambda函数
# lambda函数data['salary'].transform(lambda s: s+1)04300112400124000133900148001547001625001716001821001938001Name: salary, dtype: int64
2)多个变换函数
也可以传入包含多个变换函数的列表来一口气计算出多列结果:
data['salary'].transform([np.log, lambda s: s+1, np.sqrt])logsqrt010.66895543001207.364414110.08580924001154.919334210.59663540001200.000000310.57131739001197.48417748.987197800189.442719510.75790347001216.794834610.12663125001158.11388379.68034416001126.49110689.95227821001144.913767910.54534138001194.935887
而又因为transform传入的函数,在执行运算时接收的输入参数是对应的整列数据,所以我们可以利用这个特点实现诸如数据标准化、归一化等需要依赖样本整体统计特征的变换过程:
# 利用transform进行数据标准化data['salary'].transform(lambda s: (s - s.mean()) / s.std())00.9910381-0.46863020.76056430.6837394-1.69782551.2983376-0.3918067-1.0832288-0.69910490.606915Name: salary, dtype: float64
2、 transform作用于DataFrame 当transform作用于整个DataFrame时,实际上就是将传入的所有变换函数作用到每一列中:
data.loc[:,'salary':'age'].transform(lambda s:(s-s.mean()) /s.std())salaryage00.991038 -0.8320501 -0.4686300.10400620.7605641.66410130.6837390.9360574 -1.697825 -0.52003151.298337 -1.0400636 -0.3918061.2480757 -1.083228 -1.2480758 -0.6991040.10400690.606915 -0.416025
而当传入多个变换函数时,对应的返回结果格式类似agg中的机制,会生成MultiIndex格式的字段名
data.loc[:, 'salary': 'age'].transform([np.log, lambda s: s+1])salaryageloglog 010.668955430013.21887626110.085809240013.52636135210.596635400013.89182050310.571317390013.7376704348.98719780013.33220529510.757903470013.13549424610.126631250013.8066624679.680344160013.0445222289.952278210013.52636135910.545341380013.36729630
而且由于作用的是DataFrame,还可以利用字典以键值对的形式,一口气为每一列配置单个或多个变换函数:
(data.loc[:, 'salary': 'age'].transform({'age': lambda s: (s - s.mean()) / s.std(),'salary': [np.log, np.sqrt]}))agesalarylogsqrt0 -0.83205010.668955207.36441410.10400610.085809154.91933421.66410110.596635200.00000030.93605710.571317197.4841774 -0.5200318.98719789.4427195 -1.04006310.757903216.79483461.24807510.126631158.1138837 -1.2480759.680344126.49110680.1040069.952278144.9137679 -0.41602510.545341194.935887
3、transform作用于groupby分组后
在原来的数据中,我们知道了如何求不同公司的平均薪水,假如需要在原数据集中新增一列salary_mean,代表该公司的平均薪水,该怎么实现呢?
data['salary_mean'] = data.groupby('company')[['salary']].transform('mean')data companysalaryagesalary_mean0百度430002530333.3333331阿里240003429250.0000002百度400004930333.3333333阿里390004229250.0000004百度80002830333.3333335腾讯470002331000.0000006腾讯250004531000.0000007阿里160002129250.0000008腾讯210003431000.0000009阿里380002929250.000000
通过上面的数据可以看出,利用transform输出既得到了统计数据,形状也没有变化。
当然,也可对多个数据列进行计算
data.groupby('company')[['salary', 'age']].transform('mean')salaryage030333.33333334.0129250.00000031.5230333.33333334.0329250.00000031.5430333.33333334.0531000.00000034.0631000.00000034.0729250.00000031.5831000.00000034.0929250.00000031.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)datacompanysalaryagesalary_mean0百度430002530333.3333331阿里240003429250.0000002百度400004930333.3333333阿里390004229250.0000004百度80002830333.3333335腾讯470002331000.0000006腾讯250004531000.0000007阿里160002129250.0000008腾讯210003431000.0000009阿里380002929250.000000
以图解的方式来看看进行groupby后transform的实现过程(公司列包含ABC,salary列为每个员工的工资明细):
![分享Pandas库中的一些宝藏函数transform()](https://img.it610.com/image/info11/cf67cf34c0af4366a8407036a51dc98b.jpg)
文章图片
上图中的大方框是transform和agg 所不一样的地方,对agg而言,会计算并聚合得到 A,B,C 公司对应的均值并直接返回,每个公司一条数据,但对transform而言,则会对每一条数据求得相应的结果,同一组内的样本会有相同的值,组内求完均值后会按照原索引的顺序返回结果。
【分享Pandas库中的一些宝藏函数transform()】 以上就是分享Pandas中的一些宝藏函数transform()的详细内容,更多关于Pandas函数transform()的资料请关注脚本之家其它相关文章!
推荐阅读
- Docker应用:容器间通信与Mariadb数据库主从复制
- 太平之莲
- 第326天
- thinkphp|thinkphp 3.2 如何调用第三方类库
- 我正在参加安特思库共读一本书干法。
- 姚老师互动问答会|姚老师互动问答会 # 问题001(如何更有智慧的和身边人分享金刚智慧())
- 焦点学习田源分享第267天《来访》
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- 《偶得》
- 2018.03.18