Python类别转换无响应:20万条DataFrame转category卡顿问题
解决Pandas将字符串列转为分类变量时卡顿的问题
嘿,我太懂你这种闹心的感觉了——20万行数据转个分类变量居然卡到没响应,换谁都着急。其实直接用astype("category")有时候会因为Pandas内部自动推断分类的逻辑(比如默认排序、重复遍历校验)拖慢速度,尤其是当唯一值数量不少的时候。给你几个亲测有效的解决方案:
1. 手动指定分类值,跳过自动推断
先提前提取唯一的Location值,再用pd.Categorical创建分类列,这样能避免Pandas重复遍历整个数据集去做额外推断:
# 只遍历一次数据集,获取所有唯一的Location值 unique_locations = df['Location'].unique() # 直接创建分类列,手动指定分类集合 df['Location_Cat'] = pd.Categorical(df['Location'], categories=unique_locations, ordered=False)
这个方法会比直接astype快很多,因为它只需要两次遍历:一次提取唯一值,一次映射分类,省去了自动推断时的排序和重复校验步骤。
2. 先优化内存,再执行转换
如果你的DataFrame本身占用内存过大,会直接拖慢所有操作的速度。先检查各列内存使用情况,优化数值列的 dtype:
# 查看各列的详细内存占用(deep=True会计算字符串列的实际内存) print(df.memory_usage(deep=True)) # 优化数值列:比如将int64转成int32(只要数值范围允许) df['numeric_col1'] = df['numeric_col1'].astype('int32') # 浮点数如果不需要高精度,转成float32 df['float_col1'] = df['float_col1'].astype('float32')
释放出足够内存后,再执行分类转换,速度会有明显提升。
3. 分块处理(仅适合内存极度紧张的场景)
如果你的内存实在吃紧到连20万行都扛不住,可以把DataFrame分成小块处理,最后再合并:
# 定义分块大小,比如每5万行一块 chunk_size = 50000 chunks = [] # 遍历分块处理 for i in range(0, len(df), chunk_size): chunk = df.iloc[i:i+chunk_size].copy() # 用提前获取的唯一值创建分类列 chunk['Location_Cat'] = pd.Categorical(chunk['Location'], categories=unique_locations, ordered=False) chunks.append(chunk) # 合并所有分块 df = pd.concat(chunks, ignore_index=True)
不过20万行其实不算特别大,这个方法一般是万不得已才用。
4. 清理内存/重启内核
有时候卡顿不是转换逻辑的问题,而是之前的操作残留了太多大对象、占用了过量内存。试试手动清理内存,或者重启Python内核:
import gc # 删除无用的临时变量 del unique_locations # 如果后续不需要的话 gc.collect()
最后多说一句:3600个分类值其实不算多,转成分类变量后确实能大幅提升后续回归分析(比如虚拟变量生成、模型拟合)的效率,你的方向完全没问题,只是转换的方式需要调整~
内容的提问来源于stack exchange,提问作者user27074
相关产品推荐
相关产品推荐

