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

将Pandas宽格式DataFrame按滑动3月窗口转换为长格式

解决方法

要实现将宽格式DataFrame转换为每行包含连续3个月数据的滑动长格式,可分两步完成:先将宽表转为基础长表,再通过分组移位拼接连续月份的数据。

步骤1:将宽表转为按月的基础长表

首先用pd.wide_to_long把每个月份的列转成每行对应一个key和一个月份的长表,这是后续处理的基础:

import pandas as pd

# 原始数据
data = {
        'key':['k1','k2'],
        'name_M1':['name', 'name'],'area_M1':[1,2],'length_M1':[11,21],'breadth_M1':[12,22],
        'name_M2':['name', 'name'],'area_M2':[1,2],'length_M2':[11,21],'breadth_M2':[12,22],
        'name_M3':['name', 'name'],'area_M3':[1,2],'length_M3':[11,21],'breadth_M3':[12,22],
        'name_M4':['name', 'name'],'area_M4':[1,2],'length_M4':[11,21],'breadth_M4':[12,22],
        'name_M5':['name', 'name'],'area_M5':[1,2],'length_M5':[11,21],'breadth_M5':[12,22],
        'name_M6':['name', 'name'],'area_M6':[1,2],'length_M6':[11,21],'breadth_M6':[12,22],
       }
df = pd.DataFrame(data)

# 转换为基础长表
df_long = pd.wide_to_long(df, 
                          stubnames=['name', 'area', 'length', 'breadth'],
                          i='key', 
                          j='month',
                          sep='_',
                          suffix=r'M\d+').reset_index()

# 提取月份数字,用于排序和滑动处理
df_long['month_num'] = df_long['month'].str.extract(r'(\d+)').astype(int)
df_long = df_long.sort_values(['key', 'month_num']).reset_index(drop=True)

步骤2:分组生成滑动3个月的行

通过分组移位操作,将每个月份的下一个月、下下个月数据拼接为当前行的列,最后过滤掉不完整的行:

# 按key分组,生成第2、3个月的对应列
grouped = df_long.groupby('key')

df_long['name_2nd'] = grouped['name'].shift(-1)
df_long['area_2nd'] = grouped['area'].shift(-1)
df_long['length_2nd'] = grouped['length'].shift(-1)
df_long['breadth_2nd'] = grouped['breadth'].shift(-1)

df_long['name_3rd'] = grouped['name'].shift(-2)
df_long['area_3rd'] = grouped['area'].shift(-2)
df_long['length_3rd'] = grouped['length'].shift(-2)
df_long['breadth_3rd'] = grouped['breadth'].shift(-2)

# 过滤掉没有完整3个月数据的行(最后两行)
result = df_long.dropna(subset=['name_3rd']).reset_index(drop=True)

# 重命名列并调整顺序
result = result.rename(columns={
    'name': 'name_1st',
    'area': 'area_1st',
    'length': 'length_1st',
    'breadth': 'breadth_1st',
    'month': 'start_month'
})

final_result = result[[
    'key', 'start_month',
    'name_1st', 'area_1st', 'length_1st', 'breadth_1st',
    'name_2nd', 'area_2nd', 'length_2nd', 'breadth_2nd',
    'name_3rd', 'area_3rd', 'length_3rd', 'breadth_3rd'
]]

print(final_result)

原代码失败原因

你之前的pd.wide_to_long用法有误:stubnames参数需要对应宽表中列名的前缀(比如原表中name_M1的前缀是name),而不是直接指定最终要生成的name_1st这类列名。该方法无法直接生成滑动窗口的多行数据,需要先转成基础长表再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:20:47