问题
I'm going to post this here because it's quite a chestnut and caused me some head-scratching. It's arguably a duplicate of this question posted four years ago but I'll post it again in case someone has the specific pandas-numpy incompatibility that I have encountered here. Or maybe someone will come up with a better answer.
Code snippet:
#import pdb; pdb.set_trace()
# TODO: This raises AttributeError: 'float' object has no attribute 'sin'
xr = xw + L*np.sin(θr)
Output:
Traceback (most recent call last):
File "MIP_MPC_demo.py", line 561, in <module>
main()
File "MIP_MPC_demo.py", line 557, in main
animation = create_animation(model, data_recorder)
File "MIP_MPC_demo.py", line 358, in create_animation
xr = xw + L*np.sin(θr)
AttributeError: 'float' object has no attribute 'sin'
What I've tried so far:
(Pdb) type(np)
<class 'module'>
(Pdb) np.sin
<ufunc 'sin'>
(Pdb) type(θr)
<class 'pandas.core.series.Series'>
(Pdb) np.sin(θr.values)
*** AttributeError: 'float' object has no attribute 'sin'
(Pdb) θr.dtype
dtype('O')
(Pdb) np.sin(θr)
*** AttributeError: 'float' object has no attribute 'sin'
(Pdb) θr.sin()
*** AttributeError: 'Series' object has no attribute 'sin'
(Pdb) θr.values.sin()
*** AttributeError: 'numpy.ndarray' object has no attribute 'sin'
(Pdb) θr.values.max()
nan
(Pdb) np.max(θr)
0.02343020407511865
(Pdb) np.sin(θr)
*** AttributeError: 'float' object has no attribute 'sin'
(Pdb) np.sin(θr[0])
0.0
On a side-note, the exception is misleading to say the least. It's been four years since the other person posted the issue. Does anyone else agree that this should be modified and any suggestions on how? What is the explanation for the exception? Is numpy doing some kind of map operation and trying to call the sin
method of each element of θr
?
I will post the answer shortly...
回答1:
This fails for the same reason as:
import numpy as np
arr = np.array([1.0, 2.0, 3.0], dtype=object)
np.sin(arr)
# AttributeError: 'float' object has no attribute 'sin'
When np.sin
is called on an object array, it tries to call the sin
method of each element.
If you know the dtype of θr.values
, you can fix this with:
arr = np.array(θr.values).astype(np.float64) # assuming the type is float64
np.sin(arr) # ok!
回答2:
Quick fix if you know the possible data types of θr:
xr = xw + L*np.sin(θr.astype(float))
Better solution. Get the data type right from the beginning when creating the dataframe.
Instead of:
self.data = pd.DataFrame(index=range(n), columns=columns)
...
data.iloc[i, :] = new_data_dict
(Which I was using)
Use:
data = pd.DataFrame(index=range(n), columns=columns, dtype=float)
or:
data = pd.DataFrame(data=np.empty((n, len(columns)), columns=columns)
or:
data = pd.DataFrame(np.full((n, len(columns), np.nan), columns=columns)
来源:https://stackoverflow.com/questions/49971708/python-numpy-attributeerror-float-object-has-no-attribute-sin