如何为Pandas DataFrame两列人名分配全局统一的类别编码?
给Pandas两列的全局名称空间分配统一类别编码
嘿,这个需求我之前处理过好几次,其实用Pandas自带的工具就能轻松搞定,给你分享几个常用的实现方式:
方法一:手动构建映射字典(最灵活)
这种方法可以让你完全控制编码的起始值和名称的排序逻辑,步骤很清晰:
import pandas as pd # 你的原始DataFrame df = pd.DataFrame({"P1":["a","b","c","a"], "P2":["b","c","d","c"]}) # 1. 提取所有唯一的人名(覆盖两列的全部名称空间) all_unique_names = pd.concat([df['P1'], df['P2']]).unique() # 2. 创建名称到编码的映射(这里编码从1开始,和你的示例一致) name_code_map = {name: idx + 1 for idx, name in enumerate(all_unique_names)} # 3. 将两列替换为对应的编码 df['P1'] = df['P1'].map(name_code_map) df['P2'] = df['P2'].map(name_code_map) print(df)
运行后就会得到你想要的输出:
P1 P2 0 1 2 1 2 3 2 3 4 3 1 3
如果想要编码从0开始,只需要去掉+1就行;要是想调整名称的排序(比如按字母序),可以把all_unique_names改成sorted(pd.concat([df['P1'], df['P2']]).unique())。
方法二:用factorize()快速编码
factorize()是Pandas专门用于给唯一值分配整数编码的工具,用起来更简洁:
import pandas as pd df = pd.DataFrame({"P1":["a","b","c","a"], "P2":["b","c","d","c"]}) # 合并两列并进行编码,返回编码数组和对应的唯一值 all_codes, all_names = pd.factorize(pd.concat([df['P1'], df['P2']])) # 把编码拆分回原两列的长度,同时转成从1开始的编码 df['P1'] = all_codes[:len(df)] + 1 df['P2'] = all_codes[len(df):] + 1 print(df)
这个方法会按照名称第一次出现的顺序分配编码,和你的示例逻辑完全匹配,代码量更少。
方法三:利用Categorical类型统一类别体系
如果后续还要对这些编码做类别相关的操作,用Categorical类型会更合适,它能保证两列共享同一个类别集合:
import pandas as pd df = pd.DataFrame({"P1":["a","b","c","a"], "P2":["b","c","d","c"]}) # 定义全局的类别集合 global_categories = pd.concat([df['P1'], df['P2']]).unique() # 将两列转换为Categorical类型,并提取编码(+1转成从1开始) df['P1'] = pd.Categorical(df['P1'], categories=global_categories).codes + 1 df['P2'] = pd.Categorical(df['P2'], categories=global_categories).codes + 1 print(df)
这种方法的优势是,后续如果要新增类别或者修改编码规则,直接调整global_categories就行,两列会自动同步。
内容的提问来源于stack exchange,提问作者Shew
相关产品推荐
相关产品推荐

