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

基于列头共性合并Pandas DataFrame列的技术求助

问题:合并DataFrame中具有共性的列

我有一个包含事件和日期的DataFrame,希望解析列头,将具有共性的列合并为一列,得到指定输出。目前尝试的代码未达到预期效果(前两列存在缺失值),仅'dis'列结果正确,寻求解决方法。

输入输出示例

输入DataFrame

import pandas as pd

df1 = pd.DataFrame({'yyyyww': ['2022-01','2022-02','2022-03', '2022-01','2022-02','2022-03','2022-01','2022-03'],
                         '2001_52': [10,0,0,0,0,0,0,0],
                         '2002_52': [0,30,0,0,0,0,0,0],
                         '2003_52': [0,0,50,0,0,0,0,0],
                         '2001_23': [0,0,0,20,0,0,0,0],
                         '2002_23': [0,0,0,0,15,0,0,0],
                         'dis20': [0,0,0,0,0,25,0,0],
                         'dis30': [0,0,0,0,0,0,15,0],
                         'dis40': [0,0,0,0,0,0,0,75],})

预期输出DataFrame

df2 = pd.DataFrame({'yyyyww': ['2022-01','2022-02','2022-03', '2022-01','2022-02','2022-03','2022-01','2022-03'],
                         'wk_52': [10,30,50,0,0,0,0,0],
                         'wk_23': [0,0,0,20,15,0,0,0],
                         'dis': [0,0,0,0,0,25,15,75],})

现有尝试及问题

尝试代码

# Create empty dict 
merge_data = {}

# loop through columns to parse name 
for col in df1.columns:
    if col.startswith('2') and '_' in col:
        key = col.split('_')[-1]
        if key.isdigit():
            if key not in merge_data:
                merge_data[key] = df1[col]
        else:
            merge_data[key] +=df1[col]

# merge columns and apply values to empty dict
merge_data_out = {f"wk_{key}": values for key, values in merge_data.items()}

# procedure for combining 'dis...' columns
merge_data_out['dis'] = df1.filter(like='dis').sum(axis=1)
merge_data_out = pd.DataFrame(merge_data_out)
merge_data_out

问题说明

运行后wk_52和wk_23列仅保留了第一个匹配列的数据,其他行未完成累加,不符合预期,仅dis列结果正确。

问题分析与解决方案

问题根源

循环逻辑存在漏洞:当同key的后续列出现时,代码未执行累加操作——else分支仅针对key非数字的情况,而此处key均为数字,导致同组列无法合并。

修正方案

方法一:修复循环逻辑

import pandas as pd

df1 = pd.DataFrame({'yyyyww': ['2022-01','2022-02','2022-03', '2022-01','2022-02','2022-03','2022-01','2022-03'],
                         '2001_52': [10,0,0,0,0,0,0,0],
                         '2002_52': [0,30,0,0,0,0,0,0],
                         '2003_52': [0,0,50,0,0,0,0,0],
                         '2001_23': [0,0,0,20,0,0,0,0],
                         '2002_23': [0,0,0,0,15,0,0,0],
                         'dis20': [0,0,0,0,0,25,0,0],
                         'dis30': [0,0,0,0,0,0,15,0],
                         'dis40': [0,0,0,0,0,0,0,75],})

merge_data = {}

# 修正循环:所有同key列执行累加
for col in df1.columns:
    if col.startswith('2') and '_' in col:
        key = col.split('_')[-1]
        if key.isdigit():
            if key not in merge_data:
                # 初始化全0Series避免缺失
                merge_data[key] = pd.Series([0]*len(df1), index=df1.index)
            merge_data[key] += df1[col]

merge_data_out = {f"wk_{key}": values for key, values in merge_data.items()}
merge_data_out['dis'] = df1.filter(like='dis').sum(axis=1)
merge_data_out['yyyyww'] = df1['yyyyww']

# 调整列顺序匹配预期
df2 = pd.DataFrame(merge_data_out)[['yyyyww', 'wk_52', 'wk_23', 'dis']]
print(df2)

方法二:Pandas原生方法(推荐)

利用melt+groupby实现,代码更简洁易维护:

import pandas as pd

df1 = pd.DataFrame({'yyyyww': ['2022-01','2022-02','2022-03', '2022-01','2022-02','2022-03','2022-01','2022-03'],
                         '2001_52': [10,0,0,0,0,0,0,0],
                         '2002_52': [0,30,0,0,0,0,0,0],
                         '2003_52': [0,0,50,0,0,0,0,0],
                         '2001_23': [0,0,0,20,0,0,0,0],
                         '2002_23': [0,0,0,0,15,0,0,0],
                         'dis20': [0,0,0,0,0,25,0,0],
                         'dis30': [0,0,0,0,0,0,15,0],
                         'dis40': [0,0,0,0,0,0,0,75],})

# 处理wk_*列
wk_cols = [col for col in df1.columns if col.startswith('2') and '_' in col]
wk_df = df1.melt(id_vars='yyyyww', value_vars=wk_cols, var_name='col', value_name='value')
wk_df['wk'] = wk_df['col'].str.split('_').str[-1]
wk_sum = wk_df.groupby(['yyyyww', 'wk'])['value'].sum().unstack().add_prefix('wk_')

# 处理dis列
dis_sum = df1.filter(like='dis').sum(axis=1).rename('dis')

# 合并结果并补0
df2 = pd.concat([df1['yyyyww'], wk_sum, dis_sum], axis=1).fillna(0)
# 调整列顺序
df2 = df2[['yyyyww', 'wk_52', 'wk_23', 'dis']]
print(df2)

输出验证

两种方法均会输出与预期一致的结果:

yyyyww  wk_52  wk_23  dis
0  2022-01   10.0    0.0    0
1  2022-02   30.0    0.0    0
2  2022-03   50.0    0.0    0
3  2022-01    0.0   20.0    0
4  2022-02    0.0   15.0    0
5  2022-03    0.0    0.0   25
6  2022-01    0.0    0.0   15
7  2022-03    0.0    0.0   75

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:18:12