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

构建带标签的多时间序列整洁DataFrame,支持分组与时序分类

问题解答

一、结论:你提出的Tidy DataFrame范式是机器学习分类任务的最优选择

这种单值列、标签每行重复的结构完全契合机器学习模型(尤其是scikit-learn等主流库)的输入要求:

  • 每个样本(某一日期下某一商品的记录)对应一行
  • 所有特征(Serial、Group、Country等标签,Price等数值特征)对应列
  • 便于后续特征工程(比如时间特征拆分、分组统计、缺失值处理等)
  • 数据逻辑清晰,容易排查异常值或不一致问题

而转置回宽表结构(日期作为列)并不适合分类任务:这种结构更适合报表可视化或时序分析,但会导致特征维度冗余,且模型无法直接将多列时间值作为单一样本的输入(除非是专门的时序预测模型,而非分类任务)。

二、实现步骤(以Python pandas为例)

假设你的原始数据已读取为pandas DataFrame(第一列为行索引,对应Serial、Group、Country、日期等),具体实现如下:

1. 数据准备(模拟你的原始结构)

import pandas as pd

# 模拟用户提供的转置数据集
raw_data = {
    '12345': ['Shoes', 'Uk', 50, 40, 55, 60, -10],
    '12346': ['T-shirt', 'DE', 10, 15, 20, 30, 5]
}
row_index = ['Group', 'Country', '2020_12', '2021_01', '2021_02', '2021_03', 'pct_change_2021_01']
df = pd.DataFrame(raw_data, index=row_index)

2. 分离元数据与价格时序数据

  • 元数据:包含Serial、Group、Country等标签信息(原始数据中Serial是列名,需单独提取)
  • 价格数据:包含所有以日期开头的行
# 提取元数据:将列名(Serial)转为列,结合Group、Country行
meta_df = pd.DataFrame({
    'Serial': df.columns,
    'Group': df.loc['Group', :].values,
    'Country': df.loc['Country', :].values
})

# 提取价格时序数据并转为tidy格式
price_rows = [idx for idx in df.index if idx.startswith(('2020_', '2021_'))]
price_wide = df.loc[price_rows, :].T  # 转置后,行是Serial,列是日期
price_tidy = price_wide.reset_index().melt(
    id_vars='index',
    var_name='Date',
    value_name='Price'
).rename(columns={'index': 'Serial'})

3. 合并数据得到最终结构

# 合并元数据与tidy价格数据
final_df = price_tidy.merge(meta_df, on='Serial')

# 调整列顺序为你需要的格式
final_df = final_df[['Date', 'Price', 'Serial', 'Group', 'Country']]

print(final_df)

执行后输出的结果即为你期望的Tidy DataFrame:

Date  Price Serial    Group Country
0  2020_12     50  12345    Shoes      Uk
1  2020_12     10  12346  T-shirt      DE
2  2021_01     40  12345    Shoes      Uk
3  2021_01     15  12346  T-shirt      DE
4  2021_02     55  12345    Shoes      Uk
5  2021_02     20  12346  T-shirt      DE
6  2021_03     60  12345    Shoes      Uk
7  2021_03     30  12346  T-shirt      DE

4. 扩展:加入pct_change数据(可选)

如果需要将百分比变化数据也纳入结构,可按同样逻辑处理:

# 提取pct_change数据并转为tidy格式
pct_rows = [idx for idx in df.index if idx.startswith('pct_change_')]
pct_wide = df.loc[pct_rows, :].T
pct_tidy = pct_wide.reset_index().melt(
    id_vars='index',
    var_name='Change_Date',
    value_name='Pct_Change'
).rename(columns={'index': 'Serial'})
# 拆分Change_Date得到对应的日期
pct_tidy['Date'] = pct_tidy['Change_Date'].str.replace('pct_change_', '')

# 合并到最终数据
final_df_with_pct = final_df.merge(pct_tidy[['Serial', 'Date', 'Pct_Change']], on=['Serial', 'Date'], how='left')

三、补充说明

  • 如果你的原始数据是从文件读取(如CSV),可通过pd.read_csv(file_path, index_col=0)直接将第一列设为行索引
  • 若存在更多标签列(如Brand、Category),只需在元数据提取步骤中加入对应行即可,逻辑完全一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 22:06:32