Pandas知识点-详解转换函数transform

transform()是pandas中的转换函数,对DataFrame执行传入的函数后返回一个相同形状的DataFrame。用于对DataFrame中的数据进行转换,本文将对transform()函数进行详细介绍。

transform()参数和用法介绍

transform(func, axis=0, *args, **kwargs):

  • func: 用于转换数据的函数,函数必须满足传入一个DataFrame能正常使用,或传递到DataFrame.apply()中能正常使用。
    func可以接收函数的名字、函数名的字符串、函数组成的列表、行/列标签和函数名组成的字典。
  • axis: 设置按列还是按行转换。设置为0或index,表示对每列应用转换函数,设置为1或columns,表示对每行应用转换函数。
  • args: 传递给函数func的位置参数。
  • kwargs: 传递给函数func的关键字参数。

返回数据:

  • 返回的结果是一个与自身形状相同的DataFrame。

transform()传入单个函数

# coding=utf-8
import pandas as pd
import numpy as npdf = pd.DataFrame({'Col-1': [1, 3, 5], 'Col-2': [5, 7, 9]})
print(df)
res1 = df.transform(np.square)
print(res1)
res2 = df.transform('sqrt')
print(res2)
res3 = df.transform(lambda x: x*10)
print(res3)
   Col-1  Col-2
0      1      5
1      3      7
2      5      9Col-1  Col-2
0      1     25
1      9     49
2     25     81Col-1     Col-2
0  1.000000  2.236068
1  1.732051  2.645751
2  2.236068  3.000000Col-1  Col-2
0     10     50
1     30     70
2     50     90

在transform()中传入单个函数进行转换,transform()的结果与apply()/applymap()等效。

函数可以是库函数、自定义函数或匿名函数。因为transform()的返回结果与自身形状相同,所以不支持直接传入会将DataFrame“降维”的函数,如会将Series处理成标量的聚合函数min,mean,std等。传入这些函数时,会报错:ValueError: Function did not transform.

虽然transform()是按行/列来处理数据,但它对数据的处理有点像元素级的处理。上面这种传入单个函数对DataFrame做行列级处理的情况,更推荐使用apply()。

res4 = np.square(df)
print(res4)
   Col-1  Col-2
0      1     25
1      9     49
2     25     81

对于传入单个函数的情况,直接用函数对DataFrame处理结果也一样。

transform()传入多个函数

res5 = df.transform([np.square, np.sqrt])
print(res5)
# 传入相同名字的函数时,只有最后一个函数生效
res6 = df.transform([np.abs, lambda x: x+10, lambda x:np.square(x)])
print(res6)
   Col-1            Col-2          square      sqrt square      sqrt
0      1  1.000000     25  2.236068
1      9  1.732051     49  2.645751
2     25  2.236068     81  3.000000Col-1             Col-2         absolute <lambda> absolute <lambda>
0        1        1        5       25
1        3        9        7       49
2        5       25        9       81

在transform()中传入多个函数对DataFrame进行转换,结果中的索引变成多层索引,第一层索引是DataFrame的列名,第二层索引是执行的函数名。按第一层索引来比较,DataFrame的形状并没有变化。

在传入多个函数时,传入的方式是用列表传入,此时如果有多个名字相同的函数,只有最后一个函数生效。(聚合函数agg()中多个匿名函数可以同时生效)

按字典的方式传入函数

res7 = df.transform({'Col-1': np.square, 'Col-2': np.sqrt})
print(res7)
res8 = df.transform({'Col-1': [np.square, lambda x: x*10], 'Col-2': np.sqrt})
print(res8)
   Col-1     Col-2
0      1  2.236068
1      9  2.645751
2     25  3.000000Col-1              Col-2square <lambda>      sqrt
0      1       10  2.236068
1      9       30  2.645751
2     25       50  3.000000

在transform()中可以用字典的方式给不同的列传入不同的函数,如果字典中的value有列表,则结果的索引变成多层索引。

transform()对Series进行转换

s = pd.Series(range(3))
print(s)
res9 = s.transform(lambda x: x+10)
print(res9)
print(res9.shape)
print('-' * 20)
res10 = s.transform([np.square, lambda x: x*x])
print(res10)
print(res10.shape)
print(type(res10))
0    0
1    1
2    2
dtype: int64
0    10
1    11
2    12
dtype: int64
(3,)
--------------------square  <lambda>
0       0         0
1       1         1
2       4         4
(3, 2)
<class 'pandas.core.frame.DataFrame'>

transform()传入单个函数对Series转换时,结果是Series,传入多个函数对Series转换时,结果是DataFrame,列名是调用的函数名。

在这种情况下,Series的形状发生了变化。(也可以理解成结果是多层索引,第一层是Series的列索引,第二层是函数名,只是Series的列索引没有显示。)

与groupby()配合使用

score_df = pd.DataFrame({'姓名': ['Tom', 'Tom', 'Tom', 'Andy', 'Andy', 'Andy', 'Andy', 'Kitty', 'Kitty', 'Kitty'],'课程': ['高数', '英语', '体育', '高数', '英语', '体育', '计算机', '高数', '英语', '体育'],'成绩': [60, 90, 80, 90, 80, 70, 90, 70, 90, 80],'评级': ['C', 'A', 'B', 'A', 'B', 'C', 'A', 'C', 'A', 'B']}
)
print(score_df)
      姓名   课程  成绩 评级
0    Tom   高数  60  C
1    Tom   英语  90  A
2    Tom   体育  80  B
3   Andy   高数  90  A
4   Andy   英语  80  B
5   Andy   体育  70  C
6   Andy  计算机  90  A
7  Kitty   高数  70  C
8  Kitty   英语  90  A
9  Kitty   体育  80  B
result = score_df.groupby('姓名')['成绩'].transform(np.sum)
print('-'*30, '\n', result, sep='')
result = score_df.groupby('姓名')['成绩'].agg(np.sum)
print('-'*30, '\n', result, sep='')
------------------------------
0    230
1    230
2    230
3    330
4    330
5    330
6    330
7    240
8    240
9    240
Name: 成绩, dtype: int64
------------------------------
姓名
Andy     330
Kitty    240
Tom      230
Name: 成绩, dtype: int64

在与分组函数groupby()配合使用时,transform()转换的结果与agg()聚合的结果不一样,transform()会保持每一个分组的形状与原始数据形状相同,而agg()会将每个分组的结果聚合成一个标量值。

这是transform()和agg()最主要的功能差异,也是最有用的一点,在适合的场景里非常有用。

下面来看两个具体的案例。

案例1:计算每个人的成绩与同一门课程平均成绩的差。

score_df['平均成绩'] = score_df.groupby('课程')['成绩'].transform(np.mean)
print('-'*30, '\n', score_df, sep='')
score_df['成绩差异'] = score_df['成绩'] - score_df['平均成绩']
print('-'*30, '\n', score_df, sep='')
------------------------------姓名   课程  成绩 评级       平均成绩
0    Tom   高数  60  C  73.333333
1    Tom   英语  90  A  86.666667
2    Tom   体育  80  B  76.666667
3   Andy   高数  90  A  73.333333
4   Andy   英语  80  B  86.666667
5   Andy   体育  70  C  76.666667
6   Andy  计算机  90  A  90.000000
7  Kitty   高数  70  C  73.333333
8  Kitty   英语  90  A  86.666667
9  Kitty   体育  80  B  76.666667
------------------------------姓名   课程  成绩 评级       平均成绩       成绩差异
0    Tom   高数  60  C  73.333333 -13.333333
1    Tom   英语  90  A  86.666667   3.333333
2    Tom   体育  80  B  76.666667   3.333333
3   Andy   高数  90  A  73.333333  16.666667
4   Andy   英语  80  B  86.666667  -6.666667
5   Andy   体育  70  C  76.666667  -6.666667
6   Andy  计算机  90  A  90.000000   0.000000
7  Kitty   高数  70  C  73.333333  -3.333333
8  Kitty   英语  90  A  86.666667   3.333333
9  Kitty   体育  80  B  76.666667   3.333333

第一步,使用groupby()函数按课程分组,然后使用transform()计算出每门课程成绩的平均值。这里transform()会保证结果的形状与原来相同,极大地方便了下一步计算差值。

第二步,用成绩减平均成绩,就可以得到成绩与此门课程平均成绩的差。

实际使用时,这两个步骤可以直接合并成一步,因为“平均成绩”只是用于计算差值的中间值,不需要保存,直接一步计算出差值即可。

score_df['成绩差异'] = score_df.groupby('课程')['成绩'].transform(lambda x: x - x.mean())
print('-'*30, '\n', score_df, sep='')

案例2:填充缺失值,用每门课程的平均值填充第四位同学的成绩。

score_truman = pd.DataFrame({'姓名': ['Truman', 'Truman', 'Truman'],'课程': ['高数', '英语', '体育'],'成绩': [np.NAN, np.NAN, np.NAN],'评级': [np.NAN, np.NAN, np.NAN]}
)
score_df = pd.concat([score_df, score_truman]).reset_index()
print('-'*30, '\n', score_df, sep='')
------------------------------index      姓名   课程    成绩   评级
0       0     Tom   高数  60.0    C
1       1     Tom   英语  90.0    A
2       2     Tom   体育  80.0    B
3       3    Andy   高数  90.0    A
4       4    Andy   英语  80.0    B
5       5    Andy   体育  70.0    C
6       6    Andy  计算机  90.0    A
7       7   Kitty   高数  70.0    C
8       8   Kitty   英语  90.0    A
9       9   Kitty   体育  80.0    B
10      0  Truman   高数   NaN  NaN
11      1  Truman   英语   NaN  NaN
12      2  Truman   体育   NaN  NaN
score_df['成绩'] = score_df.groupby('课程')['成绩'].transform(lambda x: x.fillna(x.mean()))
print('-'*30, '\n', score_df, sep='')
------------------------------index      姓名   课程         成绩   评级
0       0     Tom   高数  60.000000    C
1       1     Tom   英语  90.000000    A
2       2     Tom   体育  80.000000    B
3       3    Andy   高数  90.000000    A
4       4    Andy   英语  80.000000    B
5       5    Andy   体育  70.000000    C
6       6    Andy  计算机  90.000000    A
7       7   Kitty   高数  70.000000    C
8       8   Kitty   英语  90.000000    A
9       9   Kitty   体育  80.000000    B
10      0  Truman   高数  73.333333  NaN
11      1  Truman   英语  86.666667  NaN
12      2  Truman   体育  76.666667  NaN

用平均值来填充同一组数据中的空值,这是数据处理时非常常用的方式,借用transform()可以一步完成此功能。

以上就是pandas中转换函数transform()的用法介绍和分析,如果本文的内容对你有帮助,欢迎点赞、收藏和评论,也可以关注和联系我一起交流讨论。

参考文档:
[1] pandas中文网:https://www.pypandas.cn/docs/

相关阅读:
Pandas知识点-详解聚合函数agg

Pandas知识点-详解转换函数transform相关推荐

  1. Pandas知识点-详解行列级批处理函数apply

    Pandas知识点-详解行列级批处理函数apply 在Pandas中,DataFrame和Series等对象需要执行批量处理操作时,可以借用apply()函数来实现. apply()的核心功能是实现& ...

  2. Pandas知识点-详解聚合函数agg

    Pandas知识点-详解聚合函数agg Pandas提供了多个聚合函数,聚合函数可以快速.简洁地将多个函数的执行结果聚合到一起. 本文介绍的聚合函数为DataFrame.aggregate(),别名D ...

  3. pandas:案例详解 rename函数 修改列名和行名

    pandas:案例详解rename函数 修改列名和索引 rename函数简介 0 构建学习数据 1 修改索引两种方式 2 修改列名两种方式 3 是否替换原列表 3 pandas 字母转换大小写 3 使 ...

  4. 详解虚函数的实现过程之菱形继承(5)

    大家看到标题,会不会菱形继承的虚表会不会是重复的呢?祖父类的虚表会不会在子类会不会是两份相同呢?那么我们一起来探索一下吧,冲冲冲!! 首先我们来分析一下: 它一共定义了四个类,分别为CFurnitur ...

  5. 详解虚函数的实现过程之多重继承(3)

    下面来一起探索一下多重继承时,有虚函数会怎么继承呢? 这里大家猜一下,SofaBed会占多少个字节呢? 首先我们是不是得猜一下它有几个虚表指针? 4* 4(4个int数据)+2*4(两个虚表指针)=2 ...

  6. 详解JMeter函数和变量

    详解JMeter函数和变量(1) JMeter函数可以被认为是某种特殊的变量,它们可以被采样器或者其他测试元件所引用.函数调用的语法如下: ${__functionName(var1,var2,var ...

  7. java中流_Java中流的有关知识点详解

    Java中流的有关知识点详解 发布时间:2020-09-17 03:50:59 来源:脚本之家 阅读:103 作者:mumu1998 什么是流? 流:程序和设备之间连接起来的一根用于数据传输的管道,流 ...

  8. 一分钟详解initUndistortRectifyMap函数bug修复方法

    本文首发于微信公众号「3D视觉工坊」--一分钟详解initUndistortRectifyMap函数bug修复方法 在上一篇文章OpenCV中initUndistortRectifyMap函数存在bu ...

  9. python命名空间和闭包_Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】...

    本文实例讲述了Python函数基础用法.分享给大家供大家参考,具体如下: 一.什么是命名关键字参数? 格式: 在*后面参数都是命名关键字参数. 特点: 1.约束函数的调用者必须按照Kye=value的 ...

  10. 详解虚函数的实现过程之虚基类(4)

    博客虚函数实现过程3 时提到过虚基类,这里呢,我们来详细讲述一下: 当我们在虚函数的声明结尾处添加"=0",这种虚函数就被称为纯虚函数. 它好似一个没有实现只有声明的函数,它的存在 ...

最新文章

  1. 给研发工程师的代码质量利器 | SOFAChannel#5 直播整理
  2. 华为8lite支持云闪付吗_鸿蒙系统适配机型表曝光,部分华为旗舰机未支持,你是其中之一吗...
  3. Oracle --case、while、loop、for
  4. Django(part24)--查询数据
  5. flask渲染图像_用于图像推荐的Flask应用
  6. 多帧点云数据拼接合并_PCL点云处理实践(二):点云的处理和拼接
  7. Struts2使用Interceptor实现权限控制的应用实例详解
  8. 30美元攻陷Intel SGX enclave,Intel 不打算修复
  9. 苹果Mac 上的 Spotlight 除了基本的搜寻外,还有这些快捷键技巧
  10. C# 反射应用实例-获取当前Color类的所有颜色
  11. Kvaser、C++、Qt编写监控界面(三)
  12. java ffmpge转换,java调用ffmpeg实现视频转换的方法
  13. java中23%5_23.5 jumpserver介绍
  14. 1.9w粉丝带动近100w播放量,推广黑马不止一位
  15. 安卓x5webview 加载网页 失败_#PY小贴士# 抓下来的网页为什么没有我要的内容?...
  16. 计算机网络特有的设备是什么,什么是网络设备(计算机入门知识,这些网络设备及工具你有必要知道)...
  17. 计算机英语面试翻译,计算机面试英文自我介绍范例
  18. 认认真真推荐几个优质公众号
  19. books list
  20. 视觉SLAM 关键技术与发展概述

热门文章

  1. 通过fileProvider接收外部App传递文件路径的一些坑
  2. 电脑win7做系统备份
  3. 资产证券化ABS+区块链
  4. 泰国将于5月1日全面开放,来曼谷骑行探索老城区
  5. 靶子环数图片_一种靶子环数的图像识别方法与流程
  6. 2019_IJCAI_Adapting BERT for Target-Oriented Multimodal Sentiment Classification
  7. GraphPad Prism 如何将行标签添加到数据集丨使用教程
  8. 第3章第32节:图形的应用:使用图形表达并列关系的内容 [PowerPoint精美幻灯片实战教程]
  9. uniform,attribute和varying
  10. chemdraw如何改中文_如何修改ChemDraw的默认输出格式