web-dev-qa-db-fra.com

Quelles règles Pandas utilise-t-il pour générer une vue ou une copie?

Je suis confus au sujet des règles Pandas) est utilisé pour décider qu'une sélection dans un cadre de données est une copie du cadre de données d'origine ou une vue de l'original.

Si j'ai, par exemple,

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

Je comprends qu’un query renvoie une copie de sorte que quelque chose comme

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40

n'aura aucun effet sur le dataframe d'origine, df. Je comprends également que les tranches scalaires ou nommées renvoient une vue, de sorte que les affectations à celles-ci, telles que

df.iloc[3] = 70

ou

df.ix[1,'B':'E'] = 222

va changer df. Mais je suis perdu quand il s'agit de cas plus compliqués. Par exemple,

df[df.C <= df.B]  = 7654321

change df, mais

df[df.C <= df.B].ix[:,'B':'E']

ne fait pas.

Existe-t-il une règle simple selon laquelle Pandas utilise ce que je manque simplement? Que se passe-t-il dans ces cas spécifiques? Et comment puis-je modifier toutes les valeurs (ou un sous-ensemble de valeurs)? dans un cadre de données satisfaisant une requête particulière (comme je l’essaie dans le dernier exemple ci-dessus)?


Note: Ce n'est pas la même chose que cette question ; et j'ai lu la documentation , mais je ne suis pas éclairé par cela. J'ai également lu les questions "connexes" sur ce sujet, mais il me manque encore la règle simple Pandas utilise, et comment je l'appliquerais - par exemple - modifier les valeurs (ou un sous-ensemble de valeurs) dans une trame de données qui satisfont une requête particulière.

90
orome

Voici les règles, remplacement ultérieur:

  • Toutes les opérations génèrent une copie

  • Si inplace=True est fourni, il sera modifié sur place; seules certaines opérations supportent cette

  • Un indexeur qui définit, par exemple .loc/.iloc/.iat/.at sera mis en place.

  • Un indexeur qui obtient sur un objet typé unique est presque toujours une vue (selon la disposition de la mémoire, il se peut que ce ne soit pas la raison pour laquelle ce n'est pas fiable). Ceci est principalement pour l'efficacité. (l'exemple ci-dessus est pour .query; ceci toujours retournera une copie telle qu’elle sera évaluée par numexpr)

  • Un indexeur qui obtient un objet multi-typé est toujours une copie.

Votre exemple de chained indexing

df[df.C <= df.B].loc[:,'B':'E']

n’est pas garanti de fonctionner (et donc vous devriez jamais le faire).

Au lieu de faire:

df.loc[df.C <= df.B, 'B':'E']

comme c'est plus rapide et fonctionnera toujours

L'indexation chaînée est 2 opérations distinctes python) et ne peut donc pas être interceptée de manière fiable par pandas (vous obtiendrez souvent un SettingWithCopyWarning, _], mais c'est Les dev docs , que vous avez indiqués, offrent une explication beaucoup plus complète.

104
Jeff