
本文介绍在 pandas 中安全处理含空格分隔的分数字符串(如 `'20 m b'` 或 `'25'`),通过 `str.split()` 提取主数值与可选备注,避免因字段缺失导致的 `keyerror` 或 `valueerror`。
在数据清洗中,常遇到类似 '20 M B, 25, 21' 这样的混合字符串:每个逗号分隔项是一个“分数+可选字母标注”组合,目标是将每项拆成独立行,并分离出纯数字(score)和后续备注(notes)。直接使用 str.split(' ', 1, expand=True)[1] 会因某些项无空格而报错 "KeyError: 1"——因为 expand=True 仅返回实际存在的列数(单值时只有 [0]),索引 1 不存在。
✅ 推荐方案:用 reindex() 统一列结构
最简洁、健壮的做法是强制对 split(..., expand=True) 的结果进行列对齐,确保始终存在 [0] 和 [1] 列(缺失时自动填充 NaN):
# 步骤1:按逗号切分并展开为多行
df['score'] = df['score'].str.split(r',\s*') # 使用正则处理空格,更鲁棒
df = df.explode('score').reset_index(drop=True)
# 步骤2:安全分割 score 字段 → 分离数值与备注
split_parts = df['score'].str.split(' ', n=1, expand=True).reindex(columns=[0, 1])
df['score'] = split_parts[0]
df['notes'] = split_parts[1]⚠️ 注意:n=1 表示最多分割一次(保留 'M B' 作为整体),reindex(columns=[0, 1]) 是关键——它保证即使原字符串无空格(如 '25'),也会生成两列,其中 [1] 自动为 NaN,彻底规避索引错误。
? 进阶替代:正则一步提取(更语义化)
若原始格式较规范(数字后跟空格+非逗号字符),可用 str.extractall() 直接捕获结构化信息,无需手动 explode + split:
# 提取所有匹配项(自动处理多值),并关联原表其他列 pattern = r'(?P\d+)(?:\s+(?P [^,]+))?' extracted = df['score'].str.extractall(pattern).droplevel('match') result = df.drop('score', axis=1).join(extracted)
该正则含义:
- (?P
\d+):捕获连续数字(必选); - (?:\s+(?P
[^,]+))?:非捕获组,匹配空格后任意非逗号字符(可选,命名 notes)。
✅ 优势:天然兼容无备注场景(notes 自动为 NaN),代码更声明式,且避免中间 explode 的内存开销。
? 总结建议
- 日常使用优先选 reindex() 方案:逻辑清晰、易调试、兼容性强;
- 数据量大或格式稳定时,推荐正则 extractall():性能更优、语义明确;
- 始终用 n=1 限制 split() 次数,避免误切备注中的空格(如 'M B');
- 替换 ", " 为 r',\s*' 可鲁棒处理 '20,25' 或 '20, 25' 等变体。










