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

Joh*_*ong 8 python dataframe pandas cumsum rolling-computation

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

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

 A   B   C
 1   2   3
 4   5   6
 7   8   9
10  11  12
Run Code Online (Sandbox Code Playgroud)

我上面链接的文章向您展示了如何使用cumsum()Pandas 构建一个嵌套列表的 DataFrame 列,如下所示:

[[1, 2, 3]]
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Run Code Online (Sandbox Code Playgroud)

完成此操作的 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)])
Run Code Online (Sandbox Code Playgroud)

但我想要一个滚动的列表窗口,而不是列表的累积总和。它应该是这样的:

[[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]]
Run Code Online (Sandbox Code Playgroud)

这可以用滚动对象来完成吗?

Sco*_*ton 8

这里有一些技巧可以达到你想要的结果:

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]
Run Code Online (Sandbox Code Playgroud)

输出:

[[[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]]]
Run Code Online (Sandbox Code Playgroud)

细节:

创建一个空列表。使用滚动和应用函数的技巧,该函数返回 None 和“或”运算符为零,以允许滚动应用返回 0(一个数字)。然而,我们真正追求的是函数的结果,在这种情况下是“追加”。我们使用数据帧索引作为滚动函数的输入,因此“list_of_indexes”是原始数据帧 df 索引的滚动列表。现在,让我们使用“应用元组”和“应用列表”修改数据框以将行转换为 d1 列表。

最后,让我们使用 d1 使用列表理解将我们的 list_of_indexes 替换为来自原始数据帧的适当列表。