首页 > 解决方案 > Python:使用从同一函数中的函数生成的先前值

问题描述

我试图让 ['RSIndex'] 的所有高点的滚动平均值大于 52,如果第一个 ref 值小于 52,系列将具有 NaN 值,但我希望有 ['high_r 的先前迭代值'] 如果任何其他 ref 值小于 52,则该函数已生成。如果有人对此有任何解决方案,我将不胜感激。谢谢

def AvgHigh(src, val) :
    for a in range(len(src)) :
        if src[a] > val :
            yield src[a]
        elif src[a] <= val and a == 0 :
            yield np.nan
        elif src[a] <= val and a != 0 :
            yield src[a-1]

df1['high_r'] = pd.Series(AvgHigh(df1['RSIndex'], 52))
df1['RSI_high'] = df1['high_r'].rolling(window = 25, min_periods = 25).mean()

期望的输出:

期望的输出

标签: pythonpandasdataframefunctionshift

解决方案


您可以使用np.where().shift()来简化您的代码,如下所示:

df1['high_r'] = np.where(df1['RSIndex'] > 52, df1['RSIndex'], df1['RSIndex'].shift())
df1['RSI_high'] = df1['high_r'].rolling(window = 25, min_periods = 25).mean()

np.where()检查第一个参数的条件,如果条件为真,则使用第二个参数的值[类似于if循环中的语句]。当条件为假时[类似于elif循环中的 2 个语句]。它使用第三个参数中的值。

.shift()采用前一行值[类似于您的第二条elif语句],对于没有前一个的第一个值,它采用其fill_value参数给出的值,该参数默认np.nan用于数值列。因此,它达到了与您的第一个elif设置np.nan为第一个条目相同的效果。

编辑

如果您希望从上次循环迭代中获取值而不是初始列值,您可以定义一个列表来累积循环的值,如下所示:

def AvgHigh(src, val) :
    dat_list = []
    last_src = np.nan              # init variable that keeps the prev iteration value
    for a in range(len(src)) :
        if src[a] > val :
#            yield src[a]
            dat_list.append(src[a])
            last_src = src[a]          # update prev iteration value (for subsequent iteration(s))
        elif (src[a] <= val) and (a == 0) :
#            yield np.nan
            dat_list.append(np.nan)
        elif (src[a] <= val) and (a != 0) :
#            yield src[a-1]
            dat_list.append(last_src)
        
    return dat_list

df1['high_r'] = AvgHigh(df1['RSIndex'], 52)
df1['RSI_high'] = df1['high_r'].rolling(window = 25, min_periods = 25).mean()

推荐阅读