Moi encore... :)

J'ai essayé de trouver une réponse à cette question, mais encore une fois, je n'ai pas eu la chance. Alors voilà.

Quelle est la différence entre appeler un tableau numpy (disons "iris") et tout le groupe de données de ce tableau (en utilisant iris [:] par exemple).

Je pose cette question en raison de l'erreur que j'obtiens lorsque j'exécute le premier exemple (ci-dessous), tandis que le deuxième exemple fonctionne correctement.

Voici le code:

Dans cette première partie, je charge la bibliothèque et j'importe le jeu de données depuis Internet.

import statsmodels.api as sm
iris = sm.datasets.get_rdataset(dataname='iris',
                            package='datasets')['data']

Si j'exécute ce code, j'obtiens une erreur:

iris.columns.values = [iris.columns.values[x].lower() for x in range( len( iris.columns.values ) ) ]
print(iris.columns.values)

Maintenant, si je lance ce code, cela fonctionne très bien:

iris.columns.values[:] = [iris.columns.values[x].lower() for x in range( len( iris.columns.values ) ) ]
print(iris.columns.values)

Meilleures salutations,

0
Gustavo Mirapalheta 8 mars 2019 à 03:28

2 réponses

Meilleure réponse

La différence est que lorsque vous faites iris.columns.values = ... vous essayez de remplacer la référence de la propriété values dans iris.columns qui est protégée (voir l'implémentation pandas de pandas.core.frame.DataFrame) et lorsque vous le faites iris.columns.values[:] = ... vous accédez aux données du np.ndarray et les remplacez par de nouvelles valeurs. Dans la deuxième instruction d'affectation, vous n'écrasez pas la référence à l'objet numpy. Le [:] est un objet slice qui est passé à la méthode __setitem__ du tableau numpy.

MODIFIER :

L'implémentation exacte (il y en a plusieurs, voici l'implémentation pd.Series) d'une telle propriété est :

    @property
    def values(self):
        """ return the array """
        return self.block.values

Ainsi, vous essayez d'écraser une propriété construite avec un décorateur @property suivi d'une fonction getter, et ne peut pas être remplacée car elle n'est fournie qu'avec un getter et non un setter. Voir docs Python sur les builtins - property()

2
mr_mo 8 mars 2019 à 01:39
iris.columns.values = val

Appels

type(iris.columns).__setattr__(iris.columns, 'values', val)

Il s'agit du code pandas ', car type(iris.columns) est pd.Series


iris.columns.values[:] = val

Appels

type(iris.columns.value).__setitem__(iris.columns.value, slice(None), val)

Ceci exécute le code de numpy, car type(iris.columns.value) est np.ndarray

1
Eric 8 mars 2019 à 01:39