如何使用基于涉及整行和先前数据的滚动自定义函数的 Pandas 矢量方法



虽然它易于使用的熊猫滚动方法来应用标准公式,但如果它涉及过去行有限的多列,我发现很难。使用以下代码更好地阐述: -

import numpy as np
import pandas as pd
#create dummy pandas
df=pd.DataFrame({'col1':np.arange(0,25),'col2':np.arange(100,125),'col3':np.nan})
def func1(shortdf):
#dummy formula 
#use last row of col1 multiply by sum of col2
return (shortdf.col1.tail(1).values[0]+shortdf.col2.sum())*3.14
for idx, i in df.iterrows():
if idx>3:
#only interested in the last 3 rows from position of dataframe
df.loc[idx,'col3']=func1(df.iloc[idx-3:idx])

我目前使用这种迭代方法,不用说它非常慢。 谁能有更好的建议?

选项 1

所以转移是这里的解决方案。您必须使用滚动进行求和,然后在加法和乘法后移动该序列。

df = pd.DataFrame({'col1':np.arange(0,25),'col2':np.arange(100,125),'col3':np.nan})
ans = ((df['col1'] + df['col2'].rolling(3).sum()) * 3.14).shift(1)

您可以使用ans.eq(df['col3'])检查ans是否与df['col3']相同。一旦您看到除前几个之外的所有内容都相同,只需将ans更改为df['col3'],您就可以设置好了。

选项 2

如果没有有关自定义重量功能的其他信息,就很难提供帮助。但是,此选项可能是一种解决方案,因为它以使用更多内存为代价将滚动计算分开。

# df['col3'] = ((df['col1'] + df['col2'].rolling(3).sum()) * 3.14).shift(1)
s = df['col2']
stride = pd.DataFrame([s.shift(x).values[::-1][:3] for x in range(len(s))[::-1]])
res = pd.concat([df, stride], axis=1)
# here you can perform your custom weight function
res['final'] = ((res[0] + res[1] + res[2] + res['col1']) * 3.14).shift(1)

stride改编自此问题,计算按行连接到原始数据帧。这样,每列都具有计算您可能需要的任何内容所需的值。

res['final']与选项 1 的ans相同

最新更新