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

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

  1. 计算 df1 的第 0 列前 5 行的排名
  2. 计算 df2 的第 0 列前 5 行的排名
  3. 找出两列的相关性
  4. 将此值放在第三个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。我想知道是否有更快的方法...

【问题讨论】:

    标签: python python-3.x pandas loops rolling-computation


    【解决方案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)}\n{df3[-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))
            }
        }
    )
    
    
    

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 2022-12-19
      • 2020-08-14
      • 2021-03-13
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多