如何将含多变量时间序列的DataFrame转换为三维NumPy数组?
多变量时间序列DataFrame转N×T×F格式NumPy矩阵
数据结构说明
现有DataFrame结构如下:
id:用户ID,共N个唯一值dt:日期,每个用户对应T天的连续数据- 其余列(如A、B、C、D):用户的多维度指标,共F个指标
生成示例数据的代码:
import pandas as pd from datetime import datetime import numpy as np N=5 T=100 dfs=[] datelist = pd.date_range(datetime.today(), periods=T).tolist() for id in range(N): test = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD')) test['dt'] = datelist test['id']=id dfs.append(test) dfs = pd.concat(dfs)
需求
将上述DataFrame转换为形状为N×T×F的NumPy矩阵X:
- N:用户数量
- T:每个用户的时间序列天数
- F:指标数量
要求X[0]与dfs.query('id==0')[['A','B','C','D']].values输出完全一致。
原尝试方法的问题
之前使用pivot+reshape的方法得到的结果维度顺序错误,代码如下:
# 透视DataFrame df_pivot = dfs.sort_values(['id','dt']).pivot(index='id', columns='dt') # 获取透视表的值并重塑 X = df_pivot.values.reshape(dfs['id'].nunique(), -1, len([x for x in dfs.columns if x not in ['dt','id']]))
该方法得到的X[0]是按指标维度排列时间序列,而非按时间维度排列多指标。
解决方案
方法1:使用groupby+apply
利用groupby按用户ID分组,提取每个用户的指标数据并转换为数组,最后堆叠成三维矩阵:
# 先按id和dt排序,确保时间顺序正确 dfs_sorted = dfs.sort_values(['id', 'dt']) # 提取指标列 feature_cols = [col for col in dfs.columns if col not in ['id', 'dt']] # 分组后提取每个用户的指标数组,再转换为三维矩阵 X = np.stack([group[feature_cols].values for _, group in dfs_sorted.groupby('id')])
方法2:排序后直接reshape
先确保数据按id和dt排序,然后直接通过reshape调整维度,注意顺序:
dfs_sorted = dfs.sort_values(['id', 'dt']) feature_cols = [col for col in dfs.columns if col not in ['id', 'dt']] N = dfs['id'].nunique() T = len(datelist) F = len(feature_cols) # 先提取特征值,再reshape为N×T×F X = dfs_sorted[feature_cols].values.reshape(N, T, F)
方法3:调整pivot后的轴顺序
如果坚持使用pivot方法,需要调整数组的轴顺序来匹配需求:
df_pivot = dfs.sort_values(['id','dt']).pivot(index='id', columns='dt') feature_cols = [col for col in dfs.columns if col not in ['id', 'dt']] F = len(feature_cols) # 先reshape,再转置轴的顺序 X = df_pivot.values.reshape(N, F, T).transpose(0, 2, 1)
验证
执行以下代码验证结果是否符合预期:
# 验证X[0]与目标输出一致 expected = dfs.query('id==0')[feature_cols].values print(np.array_equal(X[0], expected)) # 输出True则说明正确
内容的提问来源于stack exchange,提问作者Steven Cunden
相关产品推荐
相关产品推荐

