Reputation: 997
Me again... :)
I tried finding an answer to this question but again I was not fortunate enough. So here it is.
What is the difference between calling a numpy array (let's say "iris") and the whole group of data in this array (by using iris[:] for instance).
I´m asking this because of the error that I get when I run the first example (below), while the second example works fine.
Here is the code:
At this first part I load the library and import the dataset from the internet.
import statsmodels.api as sm
iris = sm.datasets.get_rdataset(dataname='iris',
package='datasets')['data']
If I run this code I get an error:
iris.columns.values = [iris.columns.values[x].lower() for x in range( len( iris.columns.values ) ) ]
print(iris.columns.values)
Now if I run this code it works fine:
iris.columns.values[:] = [iris.columns.values[x].lower() for x in range( len( iris.columns.values ) ) ]
print(iris.columns.values)
Best regards,
Upvotes: 0
Views: 191
Reputation: 97555
iris.columns.values = val
calls
type(iris.columns).__setattr__(iris.columns, 'values', val)
This is running pandas
' code, because type(iris.columns)
is pd.Series
iris.columns.values[:] = val
calls
type(iris.columns.value).__setitem__(iris.columns.value, slice(None), val)
This is running numpy
's code, because type(iris.columns.value)
is np.ndarray
Upvotes: 1
Reputation: 1528
The difference is that when you do iris.columns.values = ...
you try to replace the reference of the values
property in iris.columns
which is protected (see pandas implementation of pandas.core.frame.DataFrame
) and when you do iris.columns.values[:] = ...
you access the data of the np.ndarray
and replace it with new values. In the second assignment statement you do not overwrite the reference to the numpy object. The [:]
is a slice
object that is passed to the __setitem__
method of the numpy array.
EDIT:
The exact implementation (there are multiple, here is the pd.Series
implementation) of such property is:
@property
def values(self):
""" return the array """
return self.block.values
thus you try to overwrite a property that is constructed with a decorator @property
followed by a getter function, and cannot be replaced since it is only provided with a getter and not a setter. See Python's docs on builtins - property()
Upvotes: 2