
使用 `str.extract()` 配合正则表达式可精准按第一个下划线将字符串列拆分为两部分,避免 `str.split()` 产生的嵌套列表或多余下划线干扰。
在 Pandas 中,若需将一列字符串(如 'Male_85__and_over')仅按第一个下划线 _ 拆分为两个字段(gender 和 age),直接使用 str.split('_', n=1) 虽然能限制分割次数,但其返回结果为列表(如 ['Male', '85__and_over']),后续需额外处理(如 .str[1])才能提取第二部分;而若误用 .str[1:](如原代码所示),会得到包含方括号的列表对象 ['85__and_over'],导致数据类型错误和显示异常。
✅ 正确做法是使用 str.extract() 方法,配合捕获组正则表达式:
test[["gender", "age"]] = test["column_Name_pivoted"].str.extract(r'([^_]+)_([^_]+)')
- ([^_]+):匹配一个或多个非下划线字符(即首个 _ 前的内容,如 'Male');
- _:字面量下划线,作为分隔符;
- ([^_]+):匹配首个 _ 后、下一个 _ 之前的所有非下划线字符(即 '85')——⚠️注意:此正则仅适用于“首个 _ 后紧接着无 _”的场景。
但原始示例中值为 'Male_85__and_over',其首个 _ 后实际是 '85__and_over'(含多个 _)。若目标是提取 第一个 _ 后的全部剩余内容(而非截止到第二个 _),应改用更鲁棒的正则:
test[["gender", "age"]] = test["column_Name_pivoted"].str.extract(r'^([^_]+)_(.*)$')
- ^([^_]+):行首开始,捕获首个 _ 前所有非 _ 字符;
- _:匹配第一个字面量 _;
- (.*):捕获其后任意字符(包括 _)直到行尾;
- $:确保匹配到结尾,提升准确性。
? 补充说明:
- 若某行不含 _,对应位置将返回 NaN,建议提前检查:test["column_Name_pivoted"].str.contains('_').all();
- str.extract() 返回 DataFrame,可直接赋值给多列,语法简洁且类型安全;
- 相比 str.split().str[0/1],extract 更具可读性与健壮性,尤其适合结构化文本解析。
综上,推荐统一使用带锚点的正则 r'^([^_]+)_(.*)$',兼顾准确性、可维护性与边界兼容性。










