Python pandas:将函数应用于 dataframe.rolling()

Yi *_*ang 2 python pandas rolling-computation

我有这个数据框:

In[1]df = pd.DataFrame([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]])
In[2]df
Out[2]: 
    0   1   2   3   4
0   1   2   3   4   5
1   6   7   8   9  10
2  11  12  13  14  15
3  16  17  18  19  20
4  21  22  23  24  25
Run Code Online (Sandbox Code Playgroud)

我需要实现这一点:

  1. 对于我的数据框中的每一行,
  2. 如果任何 3 个连续单元格中的 2 个或更多值大于 10,
  3. 那么这 3 个单元格中的最后一个应标记为 True。

根据上述标准,生成的数据帧 df1 应与其中的 True 或 False 大小相同:

In[3]df1
Out[3]: 
    0   1      2      3      4
0 NaN NaN  False  False  False
1 NaN NaN  False  False  False
2 NaN NaN   True   True   True
3 NaN NaN   True   True   True
4 NaN NaN   True   True   True
Run Code Online (Sandbox Code Playgroud)
  • df1.iloc[0,1] 是该单元格中的 NaN 原因,只给出了两个数字,但需要至少 3 个数字来进行测试。
  • df1.iloc[1,3] 为 False,因为 [7,8,9] 中没有一个大于 10
  • df1.iloc[3,4] 为真,因为 [18,19,20] 中的 2 或更多大于 10

我认为带有函数的 dataframe.rolling.apply() 可能是解决方案,但究竟如何?

pen*_*048 6

你是对的,使用rolling()是要走的路。但是,您必须记住,因为rolling()用新值替换了窗口末尾的值,因此您不仅可以用它来标记窗口,True还会得到False只要条件不适用

以下是使用示例数据框并执行所需转换的代码:

df = pd.DataFrame([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20],[21,22,23,24,25]])
Run Code Online (Sandbox Code Playgroud)

现在,定义一个函数,将窗口作为参数并返回是否满足条件

def fun(x):
    num = 0
    for i in x:
        num += 1 if i > 10 else 0
    return 1 if num >= 2 else -1
Run Code Online (Sandbox Code Playgroud)

我已将阈值硬编码为 10。因此,如果在任何窗口中大于或等于 2 的值的数量大于或等于 2,则最后一个值将替换为 1(表示真),否则替换为 -1(表示假) )。

如果你想保持阈值参数作为变量,那么看看这个答案以将它们作为参数传递。

现在在滚动窗口上应用该函数,使用窗口大小为 3,轴 1,此外,如果您不想要 NaN,那么您还可以在参数中将 min_periods 设置为 1。

df.rolling(3, axis=1).apply(fun)
Run Code Online (Sandbox Code Playgroud)

产生输出为

  0   1    2    3    4
0 NaN NaN -1.0 -1.0 -1.0
1 NaN NaN -1.0 -1.0 -1.0
2 NaN NaN  1.0  1.0  1.0
3 NaN NaN  1.0  1.0  1.0
4 NaN NaN  1.0  1.0  1.0
Run Code Online (Sandbox Code Playgroud)