如何在Python中高效利用滑动窗口转换现有DataFrame为新结构?
高效实现滑动窗口数据转换的方案
当然有高效的实现方法!你要做的本质是时间序列的滑动窗口特征构造,这种需求在时序建模里特别常见,用Python的科学计算工具就能轻松搞定,而且效率拉满。
1. 首选:NumPy 原生滑动窗口视图(零拷贝,速度最快)
从Python 3.10开始,NumPy提供了np.lib.stride_tricks.sliding_window_view这个专门的API,它直接利用数组的内存 stride 生成滑动窗口,不需要额外复制数据,处理大规模数据集时效率极高,完全适配你说的窗口大小20的场景。
举个实际例子:
import numpy as np # 模拟你的原始数据集(单列值) raw_values = np.array([2.5, 3.7, 2.0, 4.0, 6.5, 1.6, 3.9]) window_size = 3 # 示例用3,实际换成20即可 # 一键生成滑动窗口矩阵 slided_data = np.lib.stride_tricks.sliding_window_view(raw_values, window_size) print(slided_data)
输出结果正好是你要的格式:
[[2.5 3.7 2.0] [3.7 2.0 4.0] [2.0 4.0 6.5] [4.0 6.5 1.6] [6.5 1.6 3.9]]
如果你的数据存在Pandas DataFrame里,只需要把value列转成NumPy数组,处理完再转回DataFrame就行:
import pandas as pd # 原始DataFrame df = pd.DataFrame({ 'index': range(1, 8), 'value': [2.5, 3.7, 2.0, 4.0, 6.5, 1.6, 3.9] }) window_size = 3 # 提取数值列并生成滑动窗口 values = df['value'].to_numpy() slided_matrix = np.lib.stride_tricks.sliding_window_view(values, window_size) # 构造目标格式的DataFrame result_df = pd.DataFrame( slided_matrix, columns=[f'value{i+1}' for i in range(window_size)], index=range(1, len(slided_matrix)+1) ) print(result_df)
2. 兼容老版本Python的方案
如果你的Python版本低于3.10,可以用np.lib.stride_tricks.as_strided手动实现,原理和上面一样,但需要自己计算数组的形状和步长:
def create_sliding_window(arr, window_size): n_samples = arr.shape[0] - window_size + 1 # 计算内存步长 stride = arr.strides[0] return np.lib.stride_tricks.as_strided( arr, shape=(n_samples, window_size), strides=(stride, stride) ) # 使用方法和上面一致 slided_data = create_sliding_window(raw_values, window_size)
注意:这个方法要确保n_samples是正数(也就是原始数据长度≥窗口大小),否则会出现内存越界的问题。
3. Pandas 方案(适合小窗口场景,效率略低)
如果习惯用Pandas,也可以用shift方法手动构造多列,但窗口大小为20时写起来会很繁琐;或者用rolling结合agg,但效率不如NumPy的向量化操作:
# 用shift的示例(窗口3的情况) df['value1'] = df['value'] df['value2'] = df['value'].shift(-1) df['value3'] = df['value'].shift(-2) # 过滤掉最后两行(因为shift后会出现NaN) result_df = df.dropna(subset=['value3'])[['value1', 'value2', 'value3']].reset_index(drop=True) result_df.index += 1
这种方法适合小窗口,窗口大到20的话就不推荐了,写起来麻烦还慢。
总结一下:处理大窗口(比如20)和大规模数据时,优先用NumPy的sliding_window_view,速度最快且代码简洁。
内容的提问来源于stack exchange,提问作者user8964444
相关产品推荐
相关产品推荐

