I am trying to have a rolling average of all the highs of [‘RSIndex’] greater than 52, series will have NaN value if the first ref value is less than 52, but I want to have the previous iterated value of [‘high_r’] that the function has generated if any other ref value is less than 52. If, anyone has any solution to this, i ll be really grateful. Thanks
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()
Desired Output:
Advertisement
Answer
You can use np.where()
and .shift()
to simply your codes, as follows:
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()
checks for the condition of first parameter, if the condition is true, it uses values from the second parameter [similar to your if
statement in the loop]. When the condition is false [similar to your 2 elif
statements in the loop]., it uses the values from the third parameter.
.shift()
takes the previous row value [similar to your second elif
statement] and for the first value where there is no previous, it takes the value given by its fill_value
parameter, which defaults to use np.nan
for column of numeric values. As such, it achieves the same effect of your first elif
to set np.nan
for first entry.
Edit
If you want the values to take from last loop iteration instead of initial column values, you can define a list to accumulate the values of the loop, as follows:
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()