1
import pandas as pd

def test_run():
    for symbol in ['nugt', 'soxs']:
        for stat in ['max', 'min', 'mean']:
            print(f"{stat} Close")
            print(symbol, get_stat(symbol, stat))

def get_stat(symbol, stat):
    df = pd.read_csv(f"{symbol}.csv")
    return getattr(df['close'], stat()) 

if __name__ == "__main__": 
    test_run()             

I am trying to open up an 2 excel files (soxs.csv and nugt.csv) , look at the column "close" and find the max, min, mean in the "close" column for each file.

The result I am getting is "TypeError: 'str' object is not callable". But I am calling it with attributes that should run just trying to do it with less code by using a loop. Any suggestions on how to get around this?

jpp
  • 159,742
  • 34
  • 281
  • 339
EMZ
  • 41
  • 3
  • Did one of the below solutions help? Feel free to accept one (tick on left), or ask for clarification. – jpp May 16 '18 at 11:40

3 Answers3

1

Thestat is a string so you can call it, you can get the attr by like this:

return getattr(df['close'], stat) 

It returns the method, for calling that you should use () and send the parameters if needed, like this:

return getattr(df['close'], stat)()
Mehrdad Pedramfar
  • 10,941
  • 4
  • 38
  • 59
0

You're calling the stat which is a string at following line:

return getattr(df['close'], stat()) 

Change it to:

return getattr(df['close'], stat)()

Also, for accessing multiple attributes at once you can simple use operator.attrgetter which accepts an iterable of attribute names.

e.g.

attrs = ['max', 'min', 'mean']
result = [r() for r in attrgetter(*attrs)(df['close'])]

But in this case since you need to call the getattr result again, it's not a Pythonic way to use operator.attrgetter(). Instead you could dimply loop over the attrs and just call the result manually in a list comprehension.

[getattr(df['close'], attr)() for attr in attrs]
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • When trying either of those options, my result comes out to be: "soxs " Do you know a way around that? – EMZ May 13 '18 at 08:14
  • @EMZ It seems that it's returning a bound method. You should call the result(s). – Mazdak May 13 '18 at 08:36
0

Use methdcaller instead of attrgetter for calling methods.

max, min and mean are all methods of pandas.Series, not attributes. Since methodcaller only calls one method at a time, you can apply multiple methods via a comprehension.

Here's a complete example:

from operator import methodcaller
import pandas as pd

def get_stat(df, stat):
    return {i: methodcaller(i)(df['close']) for i in stat}

df_input = pd.DataFrame({'close': [1, 2, 3, 4, 5]})

res = get_stat(df_input, ['max', 'min', 'mean'])

print(res)

{'max': 5, 'min': 1, 'mean': 3.0}
jpp
  • 159,742
  • 34
  • 281
  • 339