如何在Pandas中高效对数值列进行有序分类(不使用pd.cut)?
如何在Pandas中高效对数值列进行有序分类(不使用pd.cut)?
我完全懂你的需求!面对百万级行的大DataFrame,想给数值列做有序分类——指定值对应特定标签,其余全部归为transient,还不想走「先转字符串再转分类类型」的弯路,用pd.cut又觉得繁琐。那咱们直接来个更高效、更贴合需求的方案:
核心思路:直接生成有序分类编码,跳过字符串中间层
我们可以利用pd.Categorical.from_codes直接基于数值映射生成有序分类,全程不碰字符串转换,不管是速度还是内存占用,对大数据集都友好很多。
具体实现代码
import pandas as pd import numpy as np # 1. 定义基础映射规则和有序分类类型 MODES = [0, 9, 15, 25, 40] CATS = ['B', 'BC/2', 'BC', 'AB', 'ABC'] # 定义有序分类:transient排在最前面,后面是指定的分类标签 my_cats = pd.CategoricalDtype(categories=['transient'] + CATS, ordered=True) # 2. 准备测试数据 df = pd.DataFrame( data=[-3, 1.99, 0, 3, 9, 12, 15, 17, 24.9999999, 25, 25.000000001, 34, 40-1e-13, 40], columns=['val'] ) # 3. 高效生成有序分类列(核心步骤) # 先构建「指定值→分类编码」的映射:transient对应0,指定标签从1开始递增 code_map = {val: idx+1 for idx, val in enumerate(MODES)} # 直接通过编码生成有序分类,无需中间字符串转换 df['cat'] = pd.Categorical.from_codes( df['val'].map(code_map).fillna(0).astype(int), categories=my_cats.categories, ordered=True ) # 验证结果 print(df)
为什么这个方案更优?
- 效率拉满:全程是向量化操作,没有中间字符串转换、布尔索引赋值等冗余步骤,百万级行数据下的处理速度比原方法快很多
- 一步到位生成有序分类:直接从数值映射到分类编码,再生成
Categorical类型,完全跳过「字符串列→分类列」的转换 - 逻辑清晰易维护:映射规则和分类定义集中在一起,后续要修改标签或指定值,直接调整
MODES和CATS即可
扩展方案:用np.select处理更复杂的匹配逻辑
如果以后你的需求从「精确值匹配」扩展到「范围匹配」,可以用np.select来构建条件,同样直接生成编码:
# 构建匹配条件(这里还是精确值,你可以改成范围比如df['val'] < 0等) conditions = [df['val'] == val for val in MODES] # 对应条件的分类编码 choices = list(range(1, len(MODES)+1)) # 生成编码,默认0对应transient codes = np.select(conditions, choices, default=0) # 生成有序分类 df['cat'] = pd.Categorical.from_codes(codes, categories=my_cats.categories, ordered=True)
和原方法的结果对比
这个方案生成的df['cat']和你原代码的结果完全一致,但执行效率更高,尤其在处理超大数据集时,差异会非常明显。
内容来源于stack exchange
相关产品推荐
相关产品推荐

