将Pandas含非连续唯一整数的列映射为连续递增整数列
优雅通用地将Pandas列映射为连续递增整数序列
针对你的需求——将某列的唯一整数值按从小到大的顺序映射为从1开始的连续递增整数,以下是几种无需硬编码的通用方案:
方法1:最简洁的rank方法
直接使用Pandas的rank函数,指定method='dense'保证连续无跳号,再转为整数类型:
import pandas as pd # 示例数据 df = pd.DataFrame({'col': [10, 122, 350, 3, 27, 10, 3]}) # 生成映射后的新列 df['mapped_col'] = df['col'].rank(method='dense').astype(int)
输出结果完全匹配你要求的映射规则:
| col | mapped_col |
|---|---|
| 10 | 2 |
| 122 | 4 |
| 350 | 5 |
| 3 | 1 |
| 27 | 3 |
| 10 | 2 |
| 3 | 1 |
方法2:基于分类类型的映射
通过pd.Categorical指定排序后的唯一值作为分类项,再利用codes属性(从0开始)加1得到从1开始的序列:
# 获取排序后的唯一值列表 sorted_unique_vals = sorted(df['col'].unique()) # 转换为分类类型并生成映射列 df['mapped_col'] = pd.Categorical(df['col'], categories=sorted_unique_vals).codes + 1
这种方法适合后续需要保留分类语义的场景,同时完全通用。
方法3:手动构建映射字典(直观易懂)
自动生成排序后的唯一值与连续整数的映射字典,再用map方法批量转换:
# 构建映射字典:键为原唯一值,值为连续递增整数 mapping_dict = {val: idx+1 for idx, val in enumerate(sorted(df['col'].unique()))} # 应用映射 df['mapped_col'] = df['col'].map(mapping_dict)
这种方法的优势是可以保留映射字典,方便后续查看或复用。
为什么你之前的方法没成功?
cut:该函数用于将连续数值划分到指定区间,不适合离散唯一值的精准映射,会导致区间划分不符合需求。apply/map:如果没有先构建排序后的自动映射字典,而是手动硬编码或按出现顺序映射,就无法得到按值大小排序的连续序列。
内容的提问来源于stack exchange,提问作者Emil Frlez
相关产品推荐
相关产品推荐

