Pandas基础|生成对应编码的N种方法

举报
小小明-代码实体 发表于 2021/10/13 22:23:07 2021/10/13
【摘要】 作者:小小明 需求 已知列表 [‘50万以上’, ‘10万以下’, ‘10万以下’, ‘50万以上’, ‘10万以下’, ‘10万以下’, ‘30-50万’, ‘10-30万’] 按照以下...

作者:小小明

需求

已知列表
[‘50万以上’, ‘10万以下’, ‘10万以下’, ‘50万以上’, ‘10万以下’, ‘10万以下’, ‘30-50万’, ‘10-30万’]

按照以下关系生成编码:

  • ‘10万以下’ 1
  • ‘10-30万’ 2
  • ‘30-50万’ 3
  • ‘50万以上’ 4

对于这个基础问题,使用pandas至少有10种以上的方法去实现它,你能使用多少个API去实现,往往能体现你对Pandas方法的熟练程度,以后任何类似或更复杂的需求都不怕。下面我将演示较为常规的几种供大家复习pandas的语法。

注意:本文已经预设你掌握了pandas的全部语法,不会对基础详解。若发现对对某个API不熟悉,可查询官方文档复习。

数据构造

import pandas as pd

data = ['50万以上', '10万以下', '10万以下', '50万以上',
        '10万以下', '10万以下', '30-50万', '10-30万']
cats = ['10万以下', '10-30万', '30-50万', '50万以上']
df = pd.DataFrame({"data": data})
df

  
data
0 50万以上
1 10万以下
2 10万以下
3 50万以上
4 10万以下
5 10万以下
6 30-50万
7 10-30万

解决方法

方法1:使用pandas自带的分类数据内部编码

df.data = df.data.astype('category').cat.set_categories(cats)
df["code1"] = df.data.cat.codes+1

  

为了避免对后续代码的影响,我们将原数据还原回字符串类型:

df.data = df.data.astype('str')

  

方法2:使用python字典查询匹配

先构造一个查询字典:

query_table = dict(zip(cats, range(1, len(cats)+1)))
query_table

  
{'10万以下': 1, '10-30万': 2, '30-50万': 3, '50万以上': 4}

  

然后开始循环查询:

df["code2"] = [query_table[x] for x in df.data]

  

方法3-4:使用Series的apply方法

df["code3"] = df.data.apply(lambda x: query_table[x])

  

字典内部方法可以传入切片:

df["code4"] = df.data.apply(query_table.__getitem__)

  

方法5:使用Series的map方法传入函数

map方法也可以传入函数的:

df["code5"] = df.data.map(query_table.__getitem__)

  

方法6:使用Series的map方法传入字典

map方法除了可以传入函数外,还支持直接传入替换字典:

df["code6"] = df.data.map(query_table)

  

方法7:使用Series的replace方法

replace方法也支持直接传入替换字典:

df["code7"] = df.data.replace(query_table)

  

replace方法还支持传入正则表达式,指定参数regex=True即可,但是被替换值不能像re模块一样可以传入函数并被调用。

方法8:使用Series的str处理器的replace方法传入正则替换方法

这个方法非常智障,正则替换函数只能返回字符串,最终还需要还原成数字类型。

展示这个方法只能为了让大家清楚Series的replace方法与str处理器的replace方法的区别:

df["code8"] = df.data.str.replace('.+', lambda m: str(query_table[m.group(0)]), regex=True).astype('int')

  

方法9:使用Index的get_indexer方法获取角标位置

query_index = pd.Index(cats)
df["code9"] = query_index.get_indexer(df.data)+1

  

方法10:使用Series进行批量查询

query_series = pd.Series(index=cats, data=range(1, len(cats)+1))
df["code10"] = query_series[df.data].values

  

才哥又补充了类似下面的两种的写法:

方法11:使用merge表连接

query_frame = query_series.to_frame()
df['code11'] = df[["data"]].merge(query_frame, how='left', left_on='data', right_index=True)[0]

  

方法12:使用join表连接

df['code12'] = df[["data"]].join(query_frame, on='data')[0]

  

完整代码测试:

df.data = df.data.astype('category').cat.set_categories(cats)
df["code1"] = df.data.cat.codes+1
df.data = df.data.astype('str')

query_table = dict(zip(cats, range(1, len(cats)+1)))
df["code2"] = [query_table[x] for x in df.data]
df["code3"] = df.data.apply(lambda x: query_table[x])
df["code4"] = df.data.apply(query_table.__getitem__)

df["code5"] = df.data.map(query_table.__getitem__)
df["code6"] = df.data.map(query_table)

df["code7"] = df.data.replace(query_table)
df["code8"] = df.data.str.replace('.+', lambda m: str(query_table[m.group(0)]), regex=True).astype('int')

query_index = pd.Index(cats)
df["code9"] = query_index.get_indexer(df.data)+1

query_series = pd.Series(index=cats, data=range(1, len(cats)+1))
df["code10"] = query_series[df.data].values

query_frame = query_series.to_frame()
df['code11'] = df[["data"]].merge(query_frame, how='left', left_on='data', right_index=True)[0]
df['code12'] = df[["data"]].join(query_frame, on='data')[0]
df

  
data code1 code2 code3 code4 code5 code6 code7 code8 code9 code10 code11 code12
0 50万以上 4 4 4 4 4 4 4 4 4 4 4 4
1 10万以下 1 1 1 1 1 1 1 1 1 1 1 1
2 10万以下 1 1 1 1 1 1 1 1 1 1 1 1
3 50万以上 4 4 4 4 4 4 4 4 4 4 4 4
4 10万以下 1 1 1 1 1 1 1 1 1 1 1 1
5 10万以下 1 1 1 1 1 1 1 1 1 1 1 1
6 30-50万 3 3 3 3 3 3 3 3 3 3 3 3
7 10-30万 2 2 2 2 2 2 2 2 2 2 2 2

可以看到上述所有方法均顺利生成了对应的编码。

本文展示的方法,仅仅只是抛砖引玉,相信读者们还可能能想出更多的处理办法,欢迎留言评论进行交流。

文章来源: xxmdmst.blog.csdn.net,作者:小小明-代码实体,版权归原作者所有,如需转载,请联系作者。

原文链接:xxmdmst.blog.csdn.net/article/details/117923826

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。