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

如何用Pandas将含日期-特征键的宽格式数据转为长格式?

如何将含“日期.特征名”键的字典列表转换为长格式Pandas DataFrame?

我来帮你解决这个问题!你之前用pd.wide_to_long的时候参数搞反了,所以没得到预期结果。咱们一步步来修正:

问题分析

你的输入数据里,每个观测的键是{day}.{feature}格式,我们需要把特征名作为重复的前缀(stubnames),把日期部分提取为新的day列,最终得到包含observation_id、day、各特征列的长格式DataFrame。

正确解决方案(使用pd.wide_to_long)

这是最直接高效的方法,只需要调整参数的对应关系:

import pandas as pd

x = [
    {'observation_id': '1', '0.feature_1': 2, '0.feature_2': 2, '1.feature_1': 3, '1.feature_2': 1},
    {'observation_id': '2', '0.feature_1': 7, '0.feature_2': 3, '1.feature_1': 4, '1.feature_2': 2},
    {'observation_id': '3', '0.feature_1': 5, '0.feature_2': 2, '1.feature_1': 5, '1.feature_2': 3}
]

# 1. 先将字典列表转为初始宽表
df_wide = pd.DataFrame(x)

# 2. 使用wide_to_long转换为长表
df_long = pd.wide_to_long(
    df_wide,
    stubnames=['feature_1', 'feature_2'],  # 重复的特征前缀
    i='observation_id',                    # 标识每条原始观测的列
    j='day',                               # 要提取的新列名(日期)
    sep='.',                               # 键名的分隔符
    suffix='\d+'                           # 匹配数字类型的日期后缀
).reset_index()

# 3. 调整列顺序和示例输出一致
df_long = df_long[['observation_id', 'day', 'feature_1', 'feature_2']]
print(df_long)

运行后会得到你想要的结果:

observation_id  day  feature_1  feature_2
0              1    0          2          2
1              1    1          3          1
2              2    0          7          3
3              2    1          4          2
4              3    0          5          2
5              3    1          5          3

为什么你的代码出错了?

你之前把stubnames设成了["0", "1"],这是日期值,但stubnames的正确用法是指定那些重复出现的特征前缀(也就是feature_1、feature_2),这样函数才能识别哪些列属于同一特征的不同日期值。

进阶:动态适配未知特征名

如果你的特征数量不固定(比如以后会新增feature_3),可以自动提取特征名,不需要手动写stubnames:

# 从列名中提取所有特征名
stubnames = list({col.split('.')[1] for col in df_wide.columns if '.' in col})
stubnames.sort()  # 保证特征列顺序一致

df_long = pd.wide_to_long(
    df_wide,
    stubnames=stubnames,
    i='observation_id',
    j='day',
    sep='.',
    suffix='\d+'
).reset_index()

# 调整列顺序
df_long = df_long[['observation_id', 'day'] + stubnames]

替代方案:melt + str.split + pivot

如果需要更灵活的处理逻辑(比如键名格式更复杂),可以用这个组合方法:

# 1. 将宽表转为极长格式
melted = df_wide.melt(id_vars='observation_id', var_name='day_feature', value_name='value')

# 2. 拆分日期和特征名
melted[['day', 'feature']] = melted['day_feature'].str.split('.', expand=True)
melted['day'] = melted['day'].astype(int)  # 转为整数类型

# 3. 按特征名转回宽格式
df_long = melted.pivot(
    index=['observation_id', 'day'],
    columns='feature',
    values='value'
).reset_index()

# 清理列名层级
df_long.columns.name = None
df_long = df_long[['observation_id', 'day', 'feature_1', 'feature_2']]

内容的提问来源于stack exchange,提问作者Dar L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:47:34