You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式合并DataFrame中符合规则的多列?

pandas列合并解决方案

问题背景

我有如下所示的pandas DataFrame:

import pandas as pd

df = pd.DataFrame(
    {'number_C1_E1': ['1', '2', None, None, '5', '6', '7', '8'],
     'fruit_C11_E1': ['apple', 'banana', None, None, 'watermelon', 'peach', 'orange', 'lemon'],
     'name_C111_E1': ['tom', 'jerry', None, None, 'paul', 'edward', 'reggie', 'nicholas'],
     'number_C2_E2': [None, None, '3', None, None, None, None, None],
     'fruit_C22_E2': [None, None, 'blueberry', None, None, None, None, None],
     'name_C222_E2': [None, None, 'anthony', None, None, None, None, None],
     'number_C3_E1': [None, None, '3', '4', None, None, None, None],
     'fruit_C33_E1': [None, None, 'blueberry', 'strawberry', None, None, None, None],
     'name_C333_E1': [None, None, 'anthony', 'terry', None, None, None, None],
     }
)

合并规则

  • 若某列去除_C{0~9}、_C{0~9}{0~9}或_C{0~9}{0~9}{0~9}后缀后与另一列名称相同,则这两列可合并。

以number_C1_E1、number_C2_E2、number_C3_E1为例,number_C1_E1和number_C3_E1去除_C{0~9}后均为number_E1,因此可合并。

  • 合并后的列需要去除None值。

期望结果

number_C1_1_E1 fruit_C11_1_E1 name_C111_1_E1 number_C2_1_E2 fruit_C22_1_E2 name_C222_1_E2
0              1          apple            tom           None           None           None
1              2         banana          jerry           None           None           None
2              3      blueberry        anthony              3      blueberry        anthony
3              4     strawberry          terry           None           None           None
4              5     watermelon           paul           None           None           None
5              6          peach         edward           None           None           None
6              7         orange         reggie           None           None           None
7              8          lemon       nicholas           None           None           None

解决方案

可以通过正则表达式分组列名,再对每组列合并去空,最后调整列名实现需求,具体代码和步骤如下:

完整实现代码

import pandas as pd
import re

# 原始DataFrame
df = pd.DataFrame(
    {'number_C1_E1': ['1', '2', None, None, '5', '6', '7', '8'],
     'fruit_C11_E1': ['apple', 'banana', None, None, 'watermelon', 'peach', 'orange', 'lemon'],
     'name_C111_E1': ['tom', 'jerry', None, None, 'paul', 'edward', 'reggie', 'nicholas'],
     'number_C2_E2': [None, None, '3', None, None, None, None, None],
     'fruit_C22_E2': [None, None, 'blueberry', None, None, None, None, None],
     'name_C222_E2': [None, None, 'anthony', None, None, None, None, None],
     'number_C3_E1': [None, None, '3', '4', None, None, None, None],
     'fruit_C33_E1': [None, None, 'blueberry', 'strawberry', None, None, None, None],
     'name_C333_E1': [None, None, 'anthony', 'terry', None, None, None, None],
     }
)

# 提取列的分组键:前缀+后缀(去掉中间_C加1-3位数字的部分)
def get_group_key(col):
    match = re.match(r'^(.*)_C\d{1,3}(.*)$', col)
    if match:
        return (match.group(1), match.group(2))
    return col

# 按分组键归类所有列
column_groups = {}
for col in df.columns:
    key = get_group_key(col)
    if key not in column_groups:
        column_groups[key] = []
    column_groups[key].append(col)

# 合并每组内的列,取每行第一个非空值
merged_columns = []
for (prefix, suffix), cols in column_groups.items():
    # 用bfill/ffill实现逐行取非空值
    merged_col = df[cols].bfill(axis=1).iloc[:, 0]
    # 生成符合期望格式的新列名
    new_col_name = re.sub(r'_C(\d{1,3})', r'_C\1_1', cols[0])
    merged_columns.append(pd.DataFrame({new_col_name: merged_col}))

# 合并所有结果并调整列顺序
final_result = pd.concat(merged_columns, axis=1)
desired_col_order = ['number_C1_1_E1', 'fruit_C11_1_E1', 'name_C111_1_E1', 
                     'number_C2_1_E2', 'fruit_C22_1_E2', 'name_C222_1_E2']
final_result = final_result[desired_col_order]

print(final_result.to_string())

代码说明

  1. 分组列名:通过正则表达式^(.*)_C\d{1,3}(.*)$解析列名,把number_C1_E1和number_C3_E1这类具有相同前缀+后缀的列归为一组。
  2. 合并去空:对每组列使用bfill(axis=1)填充空值,再取第一列,得到每行的非空值。
  3. 调整列名:用正则表达式将原列名中的_C数字替换为_C数字_1,匹配期望的列名格式。
  4. 调整顺序:按照示例结果的列顺序重新排列最终DataFrame的列。

运行代码后即可得到与示例一致的输出结果。

内容的提问来源于stack exchange,提问作者haojie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:51:17