在内置“滚动”之外对 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 DataFrame 中的滚动窗口上对数据进行排名