如何用pandas/numpy实现时间序列行转列,生成滞后值与30天后值
解决方案
用pandas的shift函数就能轻松实现,核心逻辑是对Value字段做不同步长的偏移,即可得到历史几期的数值。
完整实现代码
import pandas as pd # 1. 加载原始数据 raw_data = ['Date Value Value_30days_later', '26.01.01 36 40.3', '29.01.01 36 38.2', '30.01.01 37.5 36.5', '31.01.01 37.5 37.3', '01.02.01 37 36.7', '02.02.01 37.5 36.5', '05.02.01 35 33', '06.02.01 32.5 26.5', '07.02.01 31 25.3', '08.02.01 30.5 29', '09.02.01 32.3 30.3'] # 处理成DataFrame header = raw_data[0].split() rows = [line.split() for line in raw_data[1:]] df = pd.DataFrame(rows, columns=header) # 转换字段类型 df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%y') df[['Value', 'Value_30days_later']] = df[['Value', 'Value_30days_later']].astype(float) # 确保按日期升序排列(非常重要,避免原始数据顺序错误导致结果偏差) df = df.sort_values('Date').reset_index(drop=True) # 2. 生成偏移列 lags = [4,3,2,1,0] for lag in lags: col_name = f'Value_{-lag}' if lag != 0 else 'Value_0' df[col_name] = df['Value'].shift(lag) # 3. 筛选需要的列和行(丢弃前4行无完整历史数据的记录) result_df = df[['Date', 'Value_-4', 'Value_-3', 'Value_-2', 'Value_-1', 'Value_0', 'Value_30days_later']].dropna().reset_index(drop=True) # 可选:如果需要把Date转回原来的字符串格式,可以加这一步 result_df['Date'] = result_df['Date'].dt.strftime('%d.%m.%y').str.lower() print(result_df)
输出验证
运行上述代码后得到的结果和期望的格式完全一致:
| Date | Value_-4 | Value_-3 | Value_-2 | Value_-1 | Value_0 | Value_30days_later |
|---|---|---|---|---|---|---|
| 01.02.01 | 36.0 | 36.0 | 37.5 | 37.5 | 37.0 | 36.7 |
| 02.02.01 | 36.0 | 37.5 | 37.5 | 37.0 | 37.5 | 36.5 |
| 05.02.01 | 37.5 | 37.5 | 37.0 | 37.5 | 35.0 | 33.0 |
| 06.02.01 | 37.5 | 37.0 | 37.5 | 35.0 | 32.5 | 26.5 |
| 07.02.01 | 37.0 | 37.5 | 35.0 | 32.5 | 31.0 | 25.3 |
| 08.02.01 | 37.5 | 35.0 | 32.5 | 31.0 | 30.5 | 29.0 |
| 09.02.01 | 35.0 | 32.5 | 31.0 | 30.5 | 32.3 | 30.3 |
高性能实现(大数据量场景)
如果数据量非常大,可以用numpy的滑动窗口函数sliding_window_view实现,性能会更好:
import numpy as np # 接上文df基础处理步骤 window_size = 5 values = df['Value'].values # 生成滑动窗口 windows = np.lib.stride_tricks.sliding_window_view(values, window_size) # 反转窗口顺序,对应Value_-4到Value_0的顺序 lag_cols = pd.DataFrame(windows, columns=[f'Value_{i-4}' for i in range(5)]) # 拼接其他字段 result_df = pd.concat([df.iloc[window_size-1:].reset_index(drop=True)[['Date', 'Value_30days_later']], lag_cols], axis=1)
内容的提问来源于stack exchange,提问作者StefanOverFlow
相关产品推荐
相关产品推荐

