最近在知乎上看到这样一个问题
题主表示pandas用起来很乱,事实真的如此吗?本文就将先如何利用pandas来行数据转换/编码的十种方案,最后再回答这个问题。
其实这个操作在机器学习中十分常见,很多算法都需要我们对分类特征进行转换(编码),即根据某一列的值,新增(修改)一列。
为了方便理解,下面创建示例dataframe
数值型数据 让我们先来讨论连续型数据的转换,也就是根据score列的值,来新增一列标签,即如果分数大于90,则标记为a,分数在80-90标记为b,以此类推。
自定义函数 + 循环遍历 首先当然是最简单,最笨的方法,自己写一个函数,并用循环遍历,那肯定就是一个def加一个for
df1 = df.copy()def myfun(x): if x>90: return 'a' elif x>=80 and x=70 and x=60 and x90: return 'a' elif x>=80 and x=70 and x=60 and x 90 else ( 'b' if 90 > x >= 80 else ('c' if 80 > x >= 70 else ('d' if 70 > x >= 60 else 'e')))) 结果和上面是一致的,只不过这么写容易被打。
使用 pd.cut 现在,让我们继续了解更高级的pandas函数,依旧是对 score 进行编码,使用pd.cut,并指定划分的区间后,可以直接帮你分好组
df4 = df.copy()bins = [0, 59, 70, 80, 100]df4['score_label'] = pd.cut(df4['score'], bins)
也可以直接使用labels参数来修改对应组的名称,是不是方便多了
df4['score_label_new'] = pd.cut(df4['score'], bins, labels=[ 'low', 'middle', 'good', 'perfect'])
使用 sklearn 二值化 既然是和机器学习相关,sklearn肯定跑不掉,如果需要新增一列并判定成绩是否及格,就可以使用binarizer函数,代码也是简洁好懂
df5 = df.copy()binerize = binarizer(threshold = 60)trans = binerize.fit_transform(np.array(df1['score']).reshape(-1,1))df5['score_label'] = trans
文本型数据 下面介绍更常见的,对文本数据进行转换打标签。例如新增一列,将性别男、女分别标记为0、1
使用 replace 首先介绍replace,但要注意的是,上面说过的自定义函数相关方法依旧是可行的
df6 = df.copy()df6['sex_label'] = df6['sex'].replace(['male','female'],[0,1])
上面是对性别操作,因为只有男女,所以可以手动指定0、1,但要是类别很多,也可以使用pd.value_counts()来自动指定标签,例如对course name列分组
df6 = df.copy()value = df6['course name'].value_counts()value_map = dict((v, i) for i,v in enumerate(value.index))df6['course name_label'] = df6.replace({'course name':value_map})['course name']
使用map 额外强调的是,新增一列,一定要能够想到map
df7 = df.copy()map = {elem:index for index,elem in enumerate(set(df[course name]))}df7['course name_label'] = df7['course name'].map(map)
使用astype 这个方法应该很多人不知道,这就属于上面提到的知乎问题,能实现的方法太多了
df8 = df.copy()value = df8['course name'].astype('category')df8['course name_label'] = value.cat.codes
使用 sklearn 同数值型一样,这种机器学习中的经典操作,sklearn一定有办法,使用labelencoder可以对分类数据进行编码
from sklearn.preprocessing import labelencoderdf9 = df.copy()le = labelencoder()le.fit(df9['sex'])df9['sex_label'] = le.transform(df9['sex'])le.fit(df9['course name'])df9['course name_label'] = le.transform(df9['course name'])
一次性转换两列也是可以的
df9 = df.copy()le = ordinalencoder()le.fit(df9[['sex','course name']])df9[['sex_label','course name_label']] = le.transform(df9[['sex','course name']]) 使用factorize 最后,再介绍一个小众但好用的pandas方法,我们需要注意到,在上面的方法中,自动生成的course name_label列,虽然一个数据对应一个语言,因为避免写自定义函数或者字典,这样可以自动生成,所以大多是无序的。
如果我们希望它是有序的,也就是 python 对应 0,java对应1,除了自己指定,还有什么优雅的办法?这时可以使用factorize,它会根据出现顺序进行编码
df10 = df.copy()df10['course name_label'] = pd.factorize(df10['course name'])[0]
结合匿名函数,我们可以做到对多列进行有序编码转换
df10 = df.copy()cat_columns = df10.select_dtypes(['object']).columnsdf10[['sex_label', 'course name_label']] = df10[cat_columns].apply( lambda x: pd.factorize(x)[0])
总结 至此,我们要介绍的十种pandas数据编码的方法就分享完毕,代码拿走修改变量名就能用,关于这个问题如果你有更多的方法,可以在评论区进行留言~
现在回到文章开头的问题,如果你觉得pandas用起来很乱,说明你可能还未对pandas有一个全面且彻底的了解。
其实就像本文介绍数据编码转换一样,确实有很多方法可以实现显得很乱,但学习pandas的正确姿势就是应该把它当成字典来学,不必记住所有方法与细节,你只需知道有这么个函数能完成这样操作,需要用时能想到,想到再来查就行。
原文标题:利用 pandas 进行分类数据编码的十种方式!
文章出处:【微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。
深圳飞骧科技打造高端射频中国芯,在5G移动通信产业进行布局
浅谈Linux Base System
电子产品-ESD设计分析-二
黄仁勋:NVIDIA将携手ARM共同打造AI时代首屈一指的计算公司
CODESYS变量类型的范围和所占内存大小
十种pandas数据编码的方法分享
里程碑式时刻!宁波物联网用户已经突破800万
索尼以DMP-Z1宣告:"音乐播放器就应该这样做"
Centripetal Networks诉思科诉讼败诉,法官判定思科未侵权
西门子PLC S7-200常见的71个故障汇总及解决办法
铝电解电容选型参数,How to Select Aluminum Electrolytic Capacitor
盟固利新材料、苏达汇诚、锐深科技的优秀锂电产品推荐
PyTorch教程-13.4. 硬件
IOT数据怎样来保护
商思特威科技推出车用CMOS图像传感器的LED闪烁抑制技术
钢铝复合散热器的简单介绍
福建中科明润科技梓晶微集成电路封装测试工程项目竣工
人工智能恐惧症 源自人类内心的“恶”
爱立信预测到2024年底5G全球人口覆盖率将达到45%
2018年1-8月国内智能手机市场的概况