如何将二维DataFrame转换为时间窗口化的3D数据集?
将二维DataFrame转换为滑动窗口3D数组的最佳方法
输入DataFrame
| C1 | C2 | C3 | |
|---|---|---|---|
| 0 | 2 | 3 | 6 |
| 1 | 8 | 2 | 1 |
| 2 | 8 | 6 | 2 |
| 3 | 4 | 9 | 0 |
| 4 | 6 | 7 | 1 |
| 5 | 2 | 3 | 0 |
需求说明
将上述二维DataFrame转换为形状为<num_windows, window_size, num_features>的3D数组:
- 当窗口大小
window_size=5时,总窗口数num_windows=6-5+1=2,特征数num_features=3,最终数组形状为(2,5,3)。 - 预期输出:
[[[2,3,6],[8,2,1],[8,6,2],[4,9,0],[6,7,1]], [[8,2,1],[8,6,2],[4,9,0],[6,7,1],[2,3,0]]]
最佳实现方法
方法1:Numpy Stride Tricks(高效低内存)
利用numpy的内存视图特性生成滑动窗口,无需复制数据,适合大数据量场景:
import pandas as pd import numpy as np # 构造输入DataFrame df = pd.DataFrame({ 'C1': [2, 8, 8, 4, 6, 2], 'C2': [3, 2, 6, 9, 7, 3], 'C3': [6, 1, 2, 0, 1, 0] }) window_size = 5 num_features = df.shape[1] num_windows = df.shape[0] - window_size + 1 # 转换为numpy数组 arr = df.to_numpy() # 计算步长和形状,生成滑动窗口 strides = (arr.strides[0], arr.strides[0], arr.strides[1]) shape = (num_windows, window_size, num_features) result = np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides) print(result.shape) # 输出 (2, 5, 3) print(result)
方法2:列表推导式(简洁直观)
数据量较小时,用列表推导式更易理解,代码简洁:
import pandas as pd import numpy as np df = pd.DataFrame({ 'C1': [2, 8, 8, 4, 6, 2], 'C2': [3, 2, 6, 9, 7, 3], 'C3': [6, 1, 2, 0, 1, 0] }) window_size = 5 arr = df.to_numpy() result = np.array([arr[i:i+window_size] for i in range(len(arr)-window_size+1)]) print(result.shape) # 输出 (2, 5, 3)
方法3:Pandas索引提取(结合窗口操作)
如果需要配合Pandas的rolling操作,可通过提取窗口索引生成数组:
import pandas as pd import numpy as np df = pd.DataFrame({ 'C1': [2, 8, 8, 4, 6, 2], 'C2': [3, 2, 6, 9, 7, 3], 'C3': [6, 1, 2, 0, 1, 0] }) window_size = 5 # 生成每个窗口的索引列表 window_indices = [df.index[i:i+window_size] for i in range(len(df)-window_size+1)] # 根据索引提取行并转换为3D数组 result = np.array([df.loc[idx].values for idx in window_indices]) print(result.shape) # 输出 (2, 5, 3)
方法选择建议
- 优先选Numpy Stride Tricks:性能最优,内存占用最少,适合大规模数据。
- 小数据量选列表推导式:代码简洁,易读易维护。
- 若需结合Pandas窗口分析逻辑,选索引提取法。
内容的提问来源于stack exchange,提问作者Cranjis
相关产品推荐
相关产品推荐

