首页 > 解决方案 > 如何使用基于涉及整行和先验数据的滚动自定义函数的 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])

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

标签: pandas

解决方案


选项1

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

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)

您可以检查是否ansdf['col3']使用ans.eq(df['col3']). 一旦您看到除了前几个之外的所有内容都相同,只需更改ansdf['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


推荐阅读