Gustavo Mirapalheta
Gustavo Mirapalheta

Reputation: 997

Difference between a numpy.array and numpy.array[:]

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

Answers (2)

Eric
Eric

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

mr_mo
mr_mo

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

Related Questions