使用pandas中的Rolling对象创建一个列表的滑动窗口

9

这篇杰出的文章非常清楚地说明了如何使用pandas的cumsum() DataFrame方法来构建一个包含列的3D张量,该列包含列表的列表,其维度使它们适合用作LSTM的时间序列输入。我想做类似的事情,但是要使用滚动的列表而不是累积聚合的列表。

例如,假设您有一个包含3个时间序列的DataFrame:

 A   B   C
 1   2   3
 4   5   6
 7   8   9
10  11  12

上面我提供的文章展示了如何使用pandas的cumsum()函数来构建一个类似下面这样嵌套列表的DataFrame列:
[[1, 2, 3]]
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

以下是实现此目的的关键Python代码行:
input_cols =  list(df.columns)
df['single_list'] = df[input_cols].apply(
                       tuple, axis=1).apply(list)
df['double_encapsulated'] = df.single_list.apply(
                                      lambda x: [list(x)])

但我想要一个列表的滚动窗口,而不是列表的累积和。它应该像这样:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[4, 5, 6], [7, 8, 9], [10, 11, 12]]
[[7, 8, 9], [10, 11, 12], [13, 14, 15]]

这可以用 Rolling 对象完成吗?

2个回答

9
以下是几个技巧,可以帮助您实现所需的结果:
import pandas as pd
dd = {'A': {0: 1, 1: 4, 2: 7, 3: 10, 4: 13},
 'B': {0: 2, 1: 5, 2: 8, 3: 11, 4: 14},
 'C': {0: 3, 1: 6, 2: 9, 3: 12, 4: 15}}
df = pd.DataFrame(dd)

list_of_indexes=[]
df.index.to_series().rolling(3).apply((lambda x: list_of_indexes.append(x.tolist()) or 0), raw=False)
list_of_indexes

d1 = df.apply(tuple,axis=1).apply(list)
[[d1[ix] for ix in x] for x in list_of_indexes]

输出:

[[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
 [[4, 5, 6], [7, 8, 9], [10, 11, 12]],
 [[7, 8, 9], [10, 11, 12], [13, 14, 15]]]

详细信息:

创建一个空列表。使用滚动和应用程序,使用一个返回None和“or”运算符与零的技巧函数,以允许滚动应用程序返回0(数字)。但是,我们真正需要的是函数的结果,在这种情况下是“append”。我们将数据框索引用作滚动函数的输入,因此“list_of_indexes”是原始数据框df的索引滚动列表。现在,让我们修改数据框,将行转换为列表d1,使用“apply tuple”和“apply list”。

最后,让我们使用d1使用列表推导式替换我们的list_of_indexes与origingal数据框中适当的列表。


你使用的是哪个版本的Python?我得到了以下错误:TypeError: apply() got an unexpected keyword argument 'raw'。 - John Strong
我正在使用 pandas 0.24.0。 - Scott Boston

3
自从pandas 1.1版本起,滚动对象是可迭代的,可以进行以下操作:
[win.values.tolist() for win in df.rolling(3, axis=1) if win.shape[0] == 3]

如果我们使用if语句来确保仅获取完整的窗口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接