Why do I get the 'loop of ufunc does not support argument 0 of type int' error for numpy.exp?
Asked Answered
F

4

65

I have a dataframe and I'd like to perform exponential calculation on a subset of rows in a column. I've tried three versions of code and two of them worked. But I don't understand why one version gives me the error.

import numpy as np

Version 1 (working)

np.exp(test * 1.0)

Version 2 (working)

np.exp(test.to_list())

Version 3 (Error)

np.exp(test)

It shows the error below:

AttributeError                            Traceback (most recent call last)
AttributeError: 'int' object has no attribute 'exp'

The above exception was the direct cause of the following exception:

TypeError                                 Traceback (most recent call last)
<ipython-input-161-9d5afc93942c> in <module>()
----> 1 np.exp(pd_feature.loc[(pd_feature[col] > 0) & (pd_feature[col] < 700), col])

TypeError: loop of ufunc does not support argument 0 of type int which has no callable exp method

The test data is generated by:

test = pd.loc[(pd['a'] > 0) & (pd['a'] < 650), 'a']

The data in test is just:

0      600
2      600
42     600
43     600
47     600
60     600
67     600
Name: a, dtype: Int64

and its data type is:

<class 'pandas.core.series.Series'>

However, if I try to generate a dummy dataset, it works:

data = {'a':[600, 600, 600, 600, 600, 600, 600], 'b': ['a', 'a', 'a', 'a', 'a', 'a', 'a']} 

df = pd.DataFrame(data) 

np.exp(df.loc[:,'a'])

Any idea of why I see this error? Thank you very much.

Flirtation answered 12/12, 2019 at 4:4 Comment(2)
test is an object dtype array, Try test.values.astype(float)Alti
See this answer, but ignore the use of apply, and replace log10 with exp.Grain
D
52

I guess your problem occurs because some NumPy functions explicitly require float-type arguments. Your code np.exp(test), however, has type int.

Try forcing it to be float

import numpy as np

your_array = your_array.float()
output = np.exp(your_array)

# OR

def exp_test(x)
  x.float()
  return np.exp(x)

output = exp_test(your_array)

Dicho answered 23/3, 2020 at 12:14 Comment(3)
Where is this .float() method defined? As far as I can tell numpy arrays don't have this method, and rather you'd want to use .astype(float).Theodosia
This answer is entirely wrong in both its identification of the cause of the bug, and its suggested fix.Dowry
NumPy arrays have no float method. Plus, int vs. float is a non-issue. numpy.exp works fine with arrays of int dtype, and fails with arrays of object dtype containing floats. The issue is the object dtype.Dowry
S
35

The root cause of the problem was correct in Yoshiaki's answer

I guess your problem occurs because some numpy functions require float type argument explicity, whereas your such use of the code as np.exp(test) puts int data into the argument.

However, his solution didn't work for me so I adjusted it a little bit and got it work for me

your_array = your_array.astype(float)
output = np.exp(your_array)
Sarazen answered 28/3, 2021 at 19:56 Comment(0)
F
9

Although this question has already been adequately answered, I'd like to share my experience with this issue in the hope of shedding some more light on this sort of problems and what causes them. From what I gathered, the problem is related to "numpy vs non-numpy datatypes". Here's a minimal example:

import numpy as np

arr_float = np.array([1., 2., 3.], dtype=object)
arr_float64 = arr_float.astype(float)  # The solution proposed in other answers
np.exp(arr_float)  # This throws the TypeError
np.exp(arr_float64)  # This works!

There can be various reasons for ending up with a "float-looking" object-type array, likely related to the analyzed data being pulled from a DataFrame where it was stored with an incorrect type (due to the presence of inconvertible entries), or some back-and-forth transitions between numpy and another medium (like pandas).

In conclusion - be careful with datatypes, floatnp.float64!

Firkin answered 26/1, 2022 at 10:15 Comment(0)
S
-4
test = pd.loc[(pd['a'] > 0) & (pd['a'] < 650), 'a'].values
Saks answered 10/5, 2020 at 22:29 Comment(2)
This wouldn't do anything to fix the error in the question. Anywhere this would work, the original code would have worked too.Dowry
It helps more if you supply an explanation why this is the preferred solution and explain how it works. We want to educate, not just provide code.Damascene

© 2022 - 2024 — McMap. All rights reserved.