Python : 在同一函数中使用从函数生成的先前值
Python : Use of the previous value generated from a function in the same function
我试图让 ['RSIndex'] 的所有高点的滚动平均值大于 52,如果第一个参考值小于 52,系列将具有 NaN 值,但我想要如果任何其他 ref 值小于 52,则函数生成的 ['high_r'] 的先前迭代值。如果有人对此有任何解决方案,我将非常感激。谢谢
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()
期望的输出:
您可以使用np.where()
and .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
语句]。当条件为假时[类似于循环中的 2 elif
语句],它使用第三个参数的值。
.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()
我试图让 ['RSIndex'] 的所有高点的滚动平均值大于 52,如果第一个参考值小于 52,系列将具有 NaN 值,但我想要如果任何其他 ref 值小于 52,则函数生成的 ['high_r'] 的先前迭代值。如果有人对此有任何解决方案,我将非常感激。谢谢
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()
期望的输出:
您可以使用np.where()
and .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
语句]。当条件为假时[类似于循环中的 2 elif
语句],它使用第三个参数的值。
.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()