如何用Pandas直接读取并规整含拼写变体的分类数据CSV?
处理CSV分类列拼写变体,直接生成干净的分类DataFrame
问题描述
我有一个包含多列分类数据的CSV文件,但多数分类列因输入错误存在拼写变体(例如margins列中,分类值spiculated存在'spiiculated'、'SPICULATED'等变体)。需要直接将CSV读取为干净的DataFrame,要求:
- 分类列的dtype为
category - 所有拼写变体自动合并为对应的标准分类值(拼写变体可通过预定义字典配置)
测试数据(test.csv)
margins spiculated spiiculated SPICULATED circumscribed cicumscribed
预定义变体映射字典
import pandas as pd FEAT_VALS = { "margins": { "spiculated": ["spiculated", "spiiculated", "SPICULATED"], "circumscribed": ["circumscribed", "cicumscribed"], } }
理想输出
0 spiculated 1 spiculated 2 spiculated 3 circumscribed 4 circumscribed Name: margins, dtype: category Categories (2, object): ['circumscribed', 'spiculated']
优化解决方案
方案1:读取后批量替换(高效版)
先将FEAT_VALS转换为**{变体:标准值}**的扁平映射字典,再用replace方法批量替换,比循环赋值更高效:
# 转换映射字典结构 replace_mapping = {} for col, mappings in FEAT_VALS.items(): replace_mapping[col] = {variant: std_val for std_val, variants in mappings.items() for variant in variants} # 读取数据并替换 df = pd.read_csv('test.csv') df = df.replace(replace_mapping) # 转换为category类型 df = df.astype({col: 'category' for col in FEAT_VALS.keys()}) print(df.margins)
方案2:读取阶段直接处理(更贴合需求)
利用pd.read_csv的converters参数,在读取CSV时就完成变体替换,一步得到干净的分类DataFrame:
# 为每个分类列生成转换函数 converters = {} for col, mappings in FEAT_VALS.items(): # 先构建反向映射:变体→标准值 variant_map = {} for std_val, variants in mappings.items(): for v in variants: variant_map[v] = std_val # 定义转换函数,未匹配的保持原内容(可选调整) def convert_func(x, vm=variant_map): return vm.get(x, x) converters[col] = convert_func # 读取时直接应用转换,并指定dtype df = pd.read_csv('test.csv', converters=converters, dtype={col: 'category' for col in FEAT_VALS.keys()}) print(df.margins)
对比原解决方案
原方案通过循环逐行赋值,在数据量大时效率较低。上述两种方案利用pandas的批量操作特性,性能更优,代码也更简洁。方案2直接在读取阶段完成处理,完全符合“直接读取为干净DataFrame”的需求。
内容的提问来源于stack exchange,提问作者Alek Fröhlich
相关产品推荐
相关产品推荐

