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

如何合并DataFrame中同类列至单行并复用student_id与date字段?

解决方案:将宽格式DataFrame转换为长格式

你的需求是把带有measure.N、level.N后缀的宽表,转成每行对应一组measure/level,同时保留student_id和date,这是典型的宽表转长表场景,用pandas可以轻松实现,下面提供两种实用方法:

方法一:用pd.wide_to_long(推荐,适合列名有规律的情况)

这个方法专门针对带后缀的重复列设计,代码简洁高效:

import pandas as pd

# 构造和你结构一致的示例数据(替换成你的真实DataFrame即可)
data = {
    'student_id': [804322, 3424234, 2132121],
    'date': ['9/2/2022', '9/3/2023', '4/5/2022'],
    'measure': ['some string', 'some string', 'some string'],
    'level': ['more string', 'more string', 'more string'],
    'measure.1': ['some string', 'some string', 'some string'],
    'level.1': ['more string', 'more string', 'more string'],
    'measure.2': ['some string', 'some string', 'some string'],
    'level.2': ['more string', 'more string', 'more string']
}
df = pd.DataFrame(data)

# 执行宽转长操作
df_long = pd.wide_to_long(
    df,
    stubnames=['measure', 'level'],  # 指定列名的前缀
    i=['student_id', 'date'],  # 需要保留的唯一标识列
    j='group',  # 新增列:用来区分原有的不同组(可选,不需要可以后续删除)
    sep='.',  # 列名中前缀和后缀的分隔符
    suffix=r'\d+'  # 匹配后缀的正则表达式,这里表示数字
).reset_index()

# 如果不需要group列,直接删除即可
df_long = df_long.drop(columns='group')

执行后,df_long的结构就是你想要的:每行对应一个student_id、date、measure、level,所有measure、measure.1、measure.2...的内容都合并到measure列,level列同理。

方法二:用pd.melt(灵活适配不规则列名)

如果你的列名后缀不太规则,或者需要更灵活的处理,可以用melt分别处理measure和level列,再合并:

import pandas as pd

# 构造示例数据(同上)
data = {
    'student_id': [804322, 3424234, 2132121],
    'date': ['9/2/2022', '9/3/2023', '4/5/2022'],
    'measure': ['some string', 'some string', 'some string'],
    'level': ['more string', 'more string', 'more string'],
    'measure.1': ['some string', 'some string', 'some string'],
    'level.1': ['more string', 'more string', 'more string'],
    'measure.2': ['some string', 'some string', 'some string'],
    'level.2': ['more string', 'more string', 'more string']
}
df = pd.DataFrame(data)

# 提取需要保留的标识列,以及所有measure、level相关列
id_vars = ['student_id', 'date']
measure_cols = [col for col in df.columns if 'measure' in col]
level_cols = [col for col in df.columns if 'level' in col]

# 分别对measure和level列做melt操作
df_measure = pd.melt(df, id_vars=id_vars, value_vars=measure_cols, value_name='measure')
df_level = pd.melt(df, id_vars=id_vars, value_vars=level_cols, value_name='level')

# 提取每组的编号,保证measure和level的对应关系
df_measure['group'] = df_measure['variable'].str.extract(r'(\d+)').fillna(0).astype(int)
df_level['group'] = df_level['variable'].str.extract(r'(\d+)').fillna(0).astype(int)

# 合并两个结果,得到最终长表
df_long = pd.merge(df_measure, df_level, on=['student_id', 'date', 'group'])
# 删除不需要的中间列
df_long = df_long.drop(columns=['variable_x', 'variable_y', 'group'])

验证结果

转换后的df_long示例输出大致如下:

student_iddatemeasurelevel
8043229/2/2022some stringmore string
8043229/2/2022some stringmore string
8043229/2/2022some stringmore string
34242349/3/2023some stringmore string
............

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:33:29