如何将Pandas DataFrame的每行转换为独立Series以适配sktime数据格式要求
把宽格式Pandas DataFrame转成sktime要求的单列表格格式
你遇到的是典型的宽格式转嵌套序列格式的需求,sktime要求每个样本对应一个独立的时间序列,所以需要把每行的多列数据打包成单个单元格的序列,下面给你几个简单高效的解决方案:
首先明确你的原始数据情况(这里假设time是一列,不是索引):
原始DataFrame(形状(9,7),排除time列后为(9,6)):
time 0 1 2 3 4 5 0 3.477110 3.475698 3.475874 3.478345 3.476757 3.478169 1 3.422223 3.419752 3.417987 3.421341 3.418693 3.418340 2 3.474110 3.474816 3.477463 3.479757 3.479581 3.476757 3 3.504995 3.507112 3.504995 3.505877 3.507112 3.508171 4 3.426106 3.424870 3.422399 3.421517 3.419046 3.417105 6 3.364336 3.362571 3.360453 3.358335 3.357806 3.356924 7 3.364336 3.362571 3.360453 3.358335 3.357806 3.356924 8 3.364336 3.362571 3.360453 3.358335 3.357806 3.356924
目标是转成**形状(9,1)**的DataFrame,每个单元格是长度为6的时间序列,示例如下:
time_series 0 [3.477110,3.475698,3.475874,3.478345,3.476757,3.478169] 1 [3.422223,3.419752,3.417987,3.421341,3.418693,3.418340] ...
方案1:用apply快速打包每行(最直观)
这是最容易理解的方式,直接对每行数据进行打包操作:
import pandas as pd # 假设你的原始DataFrame叫df # 先去掉time列(如果time是索引的话直接用df即可) data_cols = df.drop('time', axis=1) # 把每行转成Series,再整合成单列DataFrame df_sktime = data_cols.apply(pd.Series, axis=1).to_frame(name='time_series') # 如果想要列表格式而非Series,改成下面这行 # df_sktime = data_cols.apply(lambda row: row.tolist(), axis=1).to_frame(name='time_series')
运行后,df_sktime.shape会返回(9,1),每个单元格就是你需要的独立时间序列,直接给sktime用就行。
方案2:构造数组批量转换(性能最优)
如果你的数据量很大,apply的逐行操作可能有点慢,直接用numpy数组批量构造会更快:
# 提取数值部分的数组 values = df.drop('time', axis=1).values # 直接生成单列DataFrame,每个元素是一行的数组 df_sktime = pd.DataFrame({'time_series': [row for row in values]})
这种方法跳过了逐行遍历,性能提升明显,适合处理大规模数据集。
方案3:stack+groupby重组(灵活通用)
如果以后遇到更复杂的格式转换,用长格式转嵌套的思路也能解决:
# 把宽格式转成长格式,保留行索引 df_long = df.reset_index().melt(id_vars=['index', 'time'], var_name='pos', value_name='val') # 按行索引分组,把每组的值打包成序列 df_sktime = df_long.groupby('index')['val'].apply(pd.Series).to_frame(name='time_series')
这个方法通用性强,但对于你的需求来说,前两种更简洁。
验证一下结果,你可以打印df_sktime.iloc[0,0],应该能看到第一行的完整时间序列,完全符合sktime的输入要求。
内容的提问来源于stack exchange,提问作者Ayush Bishnoi
相关产品推荐
相关产品推荐

