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

如何用步长1、大小2的滚动前向窗口构建多变量时间序列DataFrame

问题描述

给定如下示例DataFrame:

import pandas as pd
import numpy as np
timestamps = pd.date_range(start='2017-01-01', end='2017-01-5', inclusive='left')
values = np.arange(0,len(timestamps))
df = pd.DataFrame({'A': values ,'B' : values*2},
                       index = timestamps )
print(df)

输出的原始数据:

A  B
2017-01-01  0  0
2017-01-02  1  2
2017-01-03  2  4
2017-01-04  3  6

需要实现窗口大小为2、步长为1的滚动前向采样,生成如下格式的结果:

timestep_1  timestep_2  target  
0  A 0           1           2         
   B 0           2           4         
1  A 1           2           3
   B 2           4           6

每个窗口对应一组数据,包含窗口内A、B的两个值,以及窗口右侧紧邻的A、B值作为target。尝试过pandas的rolling方法,但该方法需结合聚合函数,无法直接满足需求,寻求可行实现方案。


解决方案

可以通过滑动窗口提取+数据重组的方式实现,以下是两种高效简洁的方法:

方法一:利用shift与列重组

通过位移操作直接拼接窗口特征与目标值,再调整索引结构匹配需求:

import pandas as pd
import numpy as np

# 生成原始DataFrame
timestamps = pd.date_range(start='2017-01-01', end='2017-01-5', inclusive='left')
values = np.arange(0,len(timestamps))
df = pd.DataFrame({'A': values ,'B' : values*2}, index = timestamps )

window_size = 2
# 构造窗口内的timestep列
window_cols = pd.concat(
    [df.shift(window_size - 1 - i) for i in range(window_size)],
    axis=1,
    keys=[f'timestep_{i+1}' for i in range(window_size)]
)
# 提取窗口右侧的target值
target_col = df.shift(-1).rename(columns=lambda x: 'target')

# 合并数据并过滤无效行
result = pd.concat([window_cols, target_col], axis=1).dropna()

# 调整索引为目标层级结构
result = result.stack(level=0).swaplevel(0, 1).sort_index()
result.index.names = [None, None]

print(result)

输出结果:

timestep_1  timestep_2  target
0  A         0.0         1.0     2.0
   B         0.0         2.0     4.0
1  A         1.0         2.0     3.0
   B         2.0         4.0     6.0

方法二:利用numpy滑动窗口批量处理

针对大规模数据,使用numpy的滑动窗口可以提升处理效率:

import pandas as pd
import numpy as np

# 生成原始DataFrame
timestamps = pd.date_range(start='2017-01-01', end='2017-01-5', inclusive='left')
values = np.arange(0,len(timestamps))
df = pd.DataFrame({'A': values ,'B' : values*2}, index = timestamps )

window_size = 2
n_windows = len(df) - window_size

# 批量提取窗口数据(形状:n_windows × window_size × 列数)
window_data = np.lib.stride_tricks.sliding_window_view(df.values, window_size, axis=0)
# 提取每个窗口对应的target值
target_data = df.values[window_size:]

# 重组为目标格式
result_rows = []
for window_idx in range(n_windows):
    for col_name, win_vals, target_val in zip(df.columns, window_data[window_idx].T, target_data[window_idx]):
        result_rows.append([window_idx, col_name, win_vals[0], win_vals[1], target_val])

result = pd.DataFrame(
    result_rows,
    columns=['', '', 'timestep_1', 'timestep_2', 'target']
).set_index(['', '']).sort_index()

print(result)

输出结果与方法一完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:30:47