当前位置: 首页 > 后端技术 > Python

Pandas数据处理三轴——map、apply、applymap详解

时间:2023-03-26 10:56:08 Python

微信公众号:《Python读钱》有什么问题或者建议欢迎留言公众号在日常的数据处理中,经常会出现一个DataFrameprocessedRow-by-row,column-by-column,andelement-by-element的操作,对应这些操作,Pandas中的map、apply、applymap可以解决大部分这些数据处理需求。本文以案例附图的形式详细介绍了这三种方法的实现原理。相信看完这篇文章,无论你是Pandas的新手还是高级学习者,都会对这三种方法有更深入的了解。深入了解。本文演示的数据集是通过仿真生成的。如果你想练习,你可以根据下面的代码生成它。boolean=[True,False]gender=["Male","Female"]color=["white","black","yellow"]data=pd.DataFrame({"height":np.random.randint(150,190,100),"weight":np.random.randint(40,90,100),"smoker":[boolean[x]forxinnp.random.randint(0,2,100)],"gender":[gender[x]]]forxinnp.random.randint(0,2,100)],"age":np.random.randint(15,90,100),"color":[color[x]forxinnp.random.randint(0,len(color),100)]})数据集如下图,每一列代表身高、体重、是否吸烟、性别、年龄和肤色。系列数据处理图用法如果需要将数据集中性别列中的男性替换为1,女性替换为0,怎么办?它绝对不是用for循环实现的。它可以使用Series.map()轻松完成,至少需要一行代码。#①使用字典映射data["gender"]=data["gender"].map({"Male":1,"Female":0})#②使用函数defgender_map(x):gender=1ifx=="male"else0returngender#注意这里传入函数名,不带括号data["gender"]=data["gender"].map(gender_map),map在实际过程中是如何工作关于什么?请看下图(为了展示方便,只截取了前10条数据)。无论是使用字典还是函数进行映射,map方法都是将对应的数据作为参数,一一传入字典或函数中。映射后得到值。apply同时Series对象还有一个apply方法。apply方法的原理和map方法类似。不同的是apply可以传入功能更复杂的函数。你怎么理解的?看看下面的例子。假设在数据统计的过程中,年龄列误差较大,需要调整(加减一个值)。由于加减值未知,在定义函数时,需要多加一个参数bias,此时不能用map方法操作(传入map的函数只能接收一个参数),而apply方法可以解决这个问题。defapply_age(x,bias):returnx+bias#将附加参数作为元组传入data["age"]=data["age"].apply(apply_age,args=(-3,))可以看出age列减少了3,当然这只是一个简单的例子。当需要进行复杂的处理时,更能体现apply的作用。总而言之,对于Series,map可以解决大部分的数据处理需求,但是如果需要使用更复杂的功能,则需要使用apply方法。DataFrame数据处理apply对于DataFrame来说,apply是一个非常重要的数据处理方法。可以接收各种函数(Python内置或自定义),处理方式非常灵活。下面通过几个例子来看看apply的具体使用和原理。在具体介绍之前,首先需要介绍一下DataFrame中axis的概念。在DataFrame对象的大部分方法中,都会有一个axis参数,它控制你指定的操作是沿着0轴还是1轴进行。axis=0表示对列进行操作,axis=1表示对行进行操作,如下图所示。如果你还没有很好地理解它,没关系。下面会分别讲解沿0轴和1轴apply的操作,继续往下看。假设需要对data中的数值列进行对数和求和运算,可以使用apply进行相应的操作。因为是对列进行操作,所以需要指定axis=0,使用下面两行代码就可以很轻松的解决我们的问题。#沿0轴求和data[["height","weight","age"]].apply(np.sum,axis=0)#沿0轴取对数data[["height","Theweight","age"]].apply(np.log,axis=0)的实现很简单,但是调用apply时会发生什么?过程是如何实现的?或者通过图表的方式找出来。(以前5条数据为例)沿0轴(axis=0)操作时,每列(columns)默认会以Series的形式作为参数传递给你指定的操作函数,并合并运行后返回相应的结果。那么在实际使用中如果需要按行(axis=1)进行操作,整个过程是如何实现的呢?数据集中,有身高和体重数据,所以根据这个,我们可以计算出每个人的BMI指数(体检中常用的指标,衡量人体肥胖程度和健康程度的重要标准),计算公式为:体重指数BMI=体重/身高的平方(国际单位kg/㎡),由于每个样本都需要运算??,这里使用applywithaxis=1来运算,代码如下:defBMI(系列):weight=series["weight"]height=series["height"]/100BMI=weight/height**2returnBMIdata["BMI"]=data.apply(BMI,axis=1)或者使用图形化的方式看看这个过程是如何实现的(以前面5条数据为例)。当apply设置axis=1对行进行操作时,默认会将每一行数据以Series的形式传递给指定的函数(Series的索引为列名),并返回相应的结果。总结一下对DataFrame的apply操作:当axis=0时,对每一列执行指定的函数;当axis=1时,对每一行执行指定的函数。不管axis=0还是axis=1,传入指定函数的默认形式都是Series,可以通过设置raw=True来传入numpy数组。执行完每个Series的结果后,会将结果进行整合并返回(如果要有返回值,需要在定义函数的时候返回对应的值)。当然DataFrame的apply和Series的apply一样,也可以接收更复杂的功能。比如实现原理和传入参数是一样的。详情请参考官方文档。applymapapplymap的用法比较简单。它将对DataFrame中的每个单元格执行指定的函数操作。虽然没有apply那么广泛,但是在某些场合还是很有用的,比如下面这个例子。为了演示方便,新建一个DataFramedf=pd.DataFrame({"A":np.random.randn(5),"B":np.random.randn(5),"C":np.random.randn(5),"D":np.random.randn(5),"E":np.random.randn(5),})df现在要显示DataFrame中的所有值,保留两位小数,使用applymap可以快速达到你想要的目的,代码和图解如下:df.applymap(lambdax:"%.2f"%x)数据处理的三个技巧就介绍到这里了。如有任何疑问,请在下方积极留言!扫描二维码关注公众号《Python读钱》,干货第一时间获取!