1

I am trying to add an Average True Range column to a dataframe that contains historical stock data.

The code I am using so far is:

def add_atr_to_dataframe (dataframe):
    dataframe['ATR1'] = abs (dataframe['High'] - dataframe['Low'])
    dataframe['ATR2'] = abs (dataframe['High'] - dataframe['Close'].shift())
    dataframe['ATR3'] = abs (dataframe['Low'] - dataframe['Close'].shift())
    dataframe['TrueRange'] = max (dataframe['ATR1'], dataframe['ATR2'], dataframe['ATR3'])
    return dataframe

The last line, containing the max function, gives the error:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

I have googled for days in trying to learn how to resolve this error, or do the code in a better way, etc and have found nothing that helps me along.

Any help in the following would be much appreciated:

  1. How to resolve the error

  2. How to do the code in a better way - I do not mean that I have to code it this way and there may be better ways to do it.

Thanks ahead of time.

Igor Raush
  • 15,080
  • 1
  • 34
  • 55
ironfish
  • 161
  • 3
  • 11

2 Answers2

6

tl;dr Use

dataframe[['ATR1', 'ATR2', 'ATR3']].max(axis=1)

Explanation

You can't use the built-in max on Pandas objects. Since the first argument you are passing to max is iterable, this signature of max is invoked:

max(iterable [ , key ])

This implicitly performs a __nonzero__ (truthiness) check on the first argument to determine whether the iterable is empty, which is where your error is coming from. Numpy and Pandas objects do not coerce to booleans by design.

You are looking for something like this:

dataframe['TrueRange'] = dataframe[['ATR1', 'ATR2', 'ATR3']].max(axis=1)

This computes the maximum of the ATR* columns along the horizontal axis and returns the result as a Series, which you then add as a new TrueRange column in your dataframe.

Igor Raush
  • 15,080
  • 1
  • 34
  • 55
  • Igor, your code works perfectly! Thank you so much for responding so quickly and with such a great solution! You just ended days of frustration for me. – ironfish Mar 02 '16 at 17:37
  • No problem, see edit for why you are getting that specific error. – Igor Raush Mar 02 '16 at 17:38
  • Also, I was too hasty on the answer, your question has a duplicate [here](http://stackoverflow.com/questions/20033111/python-pandas-max-value-of-selected-columns) :) the solution they suggest is identical – Igor Raush Mar 02 '16 at 17:41
  • I just noticed that duplicate a minute ago and did not come across it in days of googling and searching this site - sorry I did not find it earlier and thanks again for taking the time to help. – ironfish Mar 02 '16 at 17:44
-1

not exactly sure if I get what you mean, but I'd suggest using pd.max() instead of max() in the problematic row.

rde
  • 31
  • 1
  • 6