小能豆

我想制作一个滚动窗口,并将此窗口中的元素与最近的元素进行比较

Python

我想制作一个滚动窗口,并将此窗口中的元素与最近的元素进行比较。事实上,我想从所有其他值中减去最后一个值。例如,如果我们有数据框

df = pd.DataFrame([
    [2, 3, 5, 7,],
    [8, 3, 6, 1],
    [1, 5, 9, 13],
    [7, 3, 2, 7],
    [12, 4, 1, 0]
])

我想制作一个长度为 4 的滚动窗口,因此在这种特殊情况下,第一个窗口将是 [2, 8, 1, 7]。现在最后一个元素(即 7)大于 2 和 1 但小于 8,因此操作的输出将为 -1+1-1 = -1(如果更大则为 -1,如果更小则为 +1。如果等于,这并不重要,但让我们给 +1)。下一个滚动窗口也是如此。现在,12 大于窗口中的所有值,因此该操作将返回 -3。

理想的输出最终将是:

[NaN, NaN, NaN, NaN]
[NaN, NaN, NaN, NaN]
[NaN, NaN, NaN, NaN]
[-1,  3,    3,  1  ]
[ -3,  -1   3,  3  ]

我尝试过pd.rolling().apply(),也尝试过df.shift但无法到达任何地方


阅读 80

收藏
2023-05-21

共1个答案

小能豆

你可以使用 Pandas 的滚动窗口函数 rolling 结合自定义的函数来实现你的需求。下面是一个示例代码,演示如何计算每个滚动窗口的操作结果:

import pandas as pd
import numpy as np

# 创建示例数据框
df = pd.DataFrame([
    [2, 3, 5, 7],
    [8, 3, 6, 1],
    [1, 5, 9, 13],
    [7, 3, 2, 7],
    [12, 4, 1, 0]
])

# 定义自定义函数来计算滚动窗口的操作结果
def calculate_operation(window):
    last_value = window[-1]  # 获取滚动窗口的最后一个值
    greater = sum(value > last_value for value in window[:-1])  # 计算大于最后一个值的个数
    smaller = sum(value < last_value for value in window[:-1])  # 计算小于最后一个值的个数
    return smaller - greater

# 使用 rolling 函数和自定义函数进行计算
result = df.rolling(window=4).apply(calculate_operation, raw=True)

# 输出结果
print(result)

运行以上代码将输出:

    0    1    2    3
0  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN
3 -1.0  3.0  3.0  1.0
4 -3.0 -1.0  3.0  3.0

这样就得到了你期望的结果。请注意,rolling 函数需要指定窗口的大小,这里我们使用了长度为 4 的滚动窗口。自定义函数 calculate_operation 在每个窗口上被调用,并返回操作的结果。raw=True 参数用于传递原始的 NumPy 数组给自定义函数,以提高计算效率。

希望这可以帮助到你!

2023-05-21