在内置“滚动”之外对 Pandas Dataframe 进行滚动窗口操作的最佳方法?

Posted

技术标签:

【中文标题】在内置“滚动”之外对 Pandas Dataframe 进行滚动窗口操作的最佳方法?【英文标题】:Best way to do rolling window operations on Pandas Dataframe outside of built in "rolling"? 【发布时间】:2020-11-19 23:47:59 【问题描述】:

我认为 Pandas 没有我想做的内置功能。假设我有 2 个 dfs,每个 1000 行。我想:

    计算 df1 的第 0 列前 5 行的排名 计算 df2 的第 0 列前 5 行的排名 找出两列的相关性 将此值放在第三个df中

我想对所有 5 的滚动窗口和所有列对执行此操作。

过去,我曾尝试通过 for 循环构建自定义滚动窗口。我会创建一个较小的 df,对其进行操作,然后创建另一个小 df,对其进行操作,等等...我的代码非常慢。

例如,我会有类似的东西:

df11 = data
df22 = data    

for i in range(df.shape[0] - 4):
        for j in range(df.shape[1]):
            df1 = df11[i:i+5, j].rank()
            df2 = df22[i:i+5, j].rank()
            df3[i + 4, j] = corr(df1, df2)

我知道上面的代码语法不正确,但你明白了。

但是循环遍历数据帧非常慢。并且有 2 个循环会更慢。我还必须随着时间的推移跟踪原始 dfs 和两个较小的 dfs。我想知道是否有更快的方法...

【问题讨论】:

【参考方案1】:

如果您想将 5 列集合的排名关联到一个 df 中,我认为它很简单,如下所示。

a = np.array(np.meshgrid([2018], [1,2,3,4,5,6], 
                     [f"Stock i+1" for i in range(600)],
                    )).reshape(3,-1)
a = [a[0], a[1], a[2], [round(random.uniform(-1,2.5),1) for e in a[0]]]
df1= pd.DataFrame("Sharpe":a[3], "Year":a[0], "Month":a[1], "Stock":a[2], )

a = [a[0], a[1], a[2], [round(random.uniform(-1,2.5),1) for e in a[0]]]
df2= pd.DataFrame("Sharpe":a[3], "Year":a[0], "Month":a[1], "Stock":a[2], )

df1["Sharpe"] = df1["Sharpe"].astype(float)
df2["Sharpe"] = df2["Sharpe"].astype(float)

df3 = pd.DataFrame(
    [[i, i+5, df1.iloc[i:i+5,0].rank().corr(df2.iloc[i:i+5,0].rank())] 
     for i in range(0, len(df1), 5)]
    ,columns=["start_row","end_row","corr"])

print(f"df3[:10].to_string(index=False)\ndf3[-10:].to_string(index=False)")

输出

 start_row  end_row      corr
         0        5  0.394737
         5       10  0.300000
        10       15  0.921053
        15       20  0.700000
        20       25 -0.410391
        25       30  0.105263
        30       35 -0.300000
        35       40  0.872082
        40       45  0.200000
        45       50  0.461690
 start_row  end_row      corr
      3550     3555 -0.153897
      3555     3560  0.718185
      3560     3565 -0.948683
      3565     3570  0.100000
      3570     3575 -0.820783
      3575     3580 -0.670820
      3580     3585 -0.131579
      3585     3590  0.102598
      3590     3595  0.872082
      3595     3600  0.872082

所有列

df3 = pd.DataFrame(
    
        **"start_row":[i for i in range(0, len(df1), 5)],
           "end_row":[i+5 for i in range(0, len(df1), 5)]
          ,
        **df1.columns[j]+"_corr":
             [df1.iloc[i:i+5,j].rank().corr(df2.iloc[i:i+5,j].rank()) 
                for i in range(0, len(df1), 5)]
                for j in range(len(df1.columns))
        
    
)


【讨论】:

以上是关于在内置“滚动”之外对 Pandas Dataframe 进行滚动窗口操作的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

加快pandas groupby中的滚动总和计算

在 pandas DataFrame 中的滚动窗口上对数据进行排名

Python数据分析 Pandas模块 基础数据结构与简介

在 pandas 中根据月份对数据进行分组,然后删除除最新的一个 Python 之外的所有条目

Pandas库的学习

肝了3天,整理了90个Pandas案例!