I currently have this code and formula:
for i in range(len(df)):
df['TrueRange'].iloc[i] = max(df['high'].iloc[i] - df['low'].iloc[i], df['high'].iloc[i] - df['close'].iloc[i-1], df['close'].iloc[i-1] - df['low'].iloc[i])
...that I would like to implement WITHOUT using a for loop as I have way too many rows for it to be efficient. I'd like it to be something like this:
df['TrueRange'] = max(df['high'] - df['low'].iloc[i], df['high'] - df['close'].iloc[i-1], df['close'].iloc[i-1] - df['low'])
...where the .iloc[i-1]
would be replaced with whatever logic was needed to utilize the previous row, just left it there as a illustration of what I'm after. However I'm not sure how to .loc
/locate the previous row's values doing it like this in the operation? Is it even possible without a for loop?
UPDATE
Using the answer below, I was getting the error:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
...due to the max() function, so what I did was this:
df['H-L'] = df['high'] - df['low']
df['H-C1'] = df['high'] - df['close'].shift()
df['C1-L'] = df['close'].shift() - df['low']
df['TrueRange'] = df[['H-L','H-C1','C1-L']].max(axis=1)
...based on the top answer taken from here. Not SUPER efficient, but it's close enough to what I need, and isn't having to iterate. Thanks!
CodePudding user response:
You can use shift
to reference previous or later rows in your dataframe.
Try something like this:
max(df['high'] - df['low'], df['high'] - df['close'].shift(), df['close'].shift() - df['low'])
CodePudding user response:
From the comments, you can use this:
max(df['high'] - df['low'], df['high'] - df['close'].shift(), df['close'].shift() - df['low'])