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

如何在Python Pandas中利用列名实现宽表转长表

解决Pandas宽表转长表的需求

嘿,这个需求其实很常见,咱们用Pandas的melt结合pivot就能轻松搞定,步骤清晰又好理解,我给你一步步演示:

首先先还原你的原始DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'student_id': [100, 101, 102],
    'q1.cta1_count': [0, 1, 1],
    'q1.cta1_date': [np.nan, '2019-03-26', '2019-03-25'],
    'q1.cta1.reminder_count': [0, 1, 0],
    'q1.cta1.reminder_date': [np.nan, '2019-03-31', np.nan]
})

接下来分四步完成转换:

第一步:用melt把宽表转成基础长格式

这一步会把所有非student_id的列“拉长”,变成包含原列名和对应值的行结构:

melted = df.melt(id_vars='student_id', var_name='col', value_name='value')

此时melted的核心结构大概是这样:

student_idcolvalue
100q1.cta1_count0
101q1.cta1_count1
.........

第二步:拆分原列名,提取type和metric

观察原列名的规律:最后一个下划线前面的部分是咱们要的type(比如q1.cta1、q1.cta1.reminder),后面的是metric(count或date)。用str.rsplit从最后一个下划线处拆分:

melted[['type', 'metric']] = melted['col'].str.rsplit('_', n=1, expand=True)

第三步:用pivot把metric转成列

这一步把count和date从行转成列,直接得到咱们想要的核心结构:

df_long = melted.pivot(index=['student_id', 'type'], columns='metric', values='value').reset_index()

第四步:整理格式和排序

最后去掉多余的列名层级,调整顺序并按需求排序:

# 移除列名的层级标签
df_long.columns.name = None
# 按student_id和type排序,重置索引
df_long = df_long.sort_values(['student_id', 'type']).reset_index(drop=True)

最终得到的df_long就是你要的长格式:

student_id               type  count        date
0         100           q1.cta1      0         NaN
1         100  q1.cta1.reminder      0         NaN
2         101           q1.cta1      1  2019-03-26
3         101  q1.cta1.reminder      1  2019-03-31
4         102           q1.cta1      1  2019-03-25
5         102  q1.cta1.reminder      0         NaN

这个方法通用性很强,不管你的type前缀有多少个点,只要最后是_count或_date的格式,都能完美适配~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:12:59