Lors de la sélection d'une sous-trame de données à partir d'une trame de données parent, j'ai remarqué que certains programmeurs font une copie de la trame de données à l'aide de la .copy()
méthode. Par exemple,
X = my_dataframe[features_list].copy()
... au lieu de juste
X = my_dataframe[features_list]
Pourquoi font-ils une copie de la trame de données? Que se passera-t-il si je ne fais pas de copie?
python
pandas
chained-assignment
Elizabeth Susan Joseph
la source
la source
Réponses:
Cela élargit la réponse de Paul. Dans Pandas, l'indexation d'un DataFrame renvoie une référence au DataFrame initial. Ainsi, la modification du sous-ensemble modifiera le DataFrame initial. Ainsi, vous voudrez utiliser la copie si vous voulez vous assurer que le DataFrame initial ne doit pas changer. Considérez le code suivant:
Tu auras:
En revanche, ce qui suit laisse df inchangé:
la source
Parce que si vous ne faites pas de copie, les index peuvent toujours être manipulés ailleurs, même si vous affectez le dataFrame à un nom différent.
Par exemple:
func1 peut modifier df en modifiant df2, donc pour éviter que:
la source
, both variables reference the same DataFrame instance. So any changes made to
df` oudf2
sera fait sur la même instance d'objet. Alors que dans ladf2 = df.copy()
seconde instance d'objet est créée, une copie de la première, mais maintenantdf
etdf2
référence à différentes instances d'objet et toutes les modifications seront apportées à leur instance DataFrame respective.Il est nécessaire de mentionner que le retour de la copie ou de la vue dépend du type d'indexation.
La documentation des pandas dit:
la source
L'objectif principal est d'éviter l'indexation chaînée et d'éliminer les fichiers
SettingWithCopyWarning
.Ici, l'indexation chaînée est quelque chose comme
dfc['A'][0] = 111
Le document a déclaré que l'indexation chaînée devrait être évitée dans Renvoyer une vue par rapport à une copie . Voici un exemple légèrement modifié de ce document:
Ici, il
aColumn
s'agit d'une vue et non d'une copie du DataFrame d'origine, donc la modificationaColumn
entraînera également la modification de l'originaldfc
. Ensuite, si nous indexons la ligne en premier:Cette fois
zero_row
est une copie, donc l'originaldfc
n'est pas modifié.À partir de ces deux exemples ci-dessus, nous voyons qu'il est ambigu que vous souhaitiez ou non modifier le DataFrame d'origine. Ceci est particulièrement dangereux si vous écrivez quelque chose comme ce qui suit:
Cette fois, ça n'a pas marché du tout. Ici, nous voulions changer
dfc
, mais nous avons en fait modifié une valeur intermédiairedfc.loc[0]
qui est une copie et est immédiatement supprimée. Il est très difficile de prédire si la valeur intermédiaire aimedfc.loc[0]
oudfc['A']
est une vue ou une copie, il n'est donc pas garanti si le DataFrame d'origine sera mis à jour ou non. C'est pourquoi l'indexation chaînée doit être évitée, et pandas génère leSettingWithCopyWarning
pour ce type de mise à jour d'indexation chaînée.C'est maintenant l'utilisation de
.copy()
. Pour éliminer l'avertissement, faites une copie pour exprimer explicitement votre intention:Puisque vous modifiez une copie, vous savez que l'original
dfc
ne changera jamais et vous ne vous attendez pas à ce qu'il change. Votre attente correspond au comportement, puisSettingWithCopyWarning
disparaît.Remarque: si vous souhaitez modifier le DataFrame d'origine, le document vous suggère d'utiliser
loc
:la source
En général, il est plus sûr de travailler sur des copies que sur des blocs de données d'origine, sauf lorsque vous savez que vous n'aurez plus besoin de l'original et que vous souhaitez continuer avec la version manipulée. Normalement, vous auriez encore une certaine utilité pour la trame de données originale à comparer avec la version manipulée, etc. Par conséquent, la plupart des gens travaillent sur des copies et fusionnent à la fin.
la source
Supposons que vous ayez un bloc de données comme ci-dessous
Lorsque vous souhaitez en créer un autre
df2
identique àdf1
, sanscopy
Et souhaite modifier la valeur df2 uniquement comme ci-dessous
En même temps, le df1 est également modifié
Puisque deux df sont identiques
object
, nous pouvons le vérifier en utilisant leid
Donc, comme même objet et un changement, un autre passera également la même valeur.
Si nous ajoutons les
copy
, et maintenantdf1
etdf2
sont considérés comme différentsobject
, si nous apportons le même changement à l'un d'eux, l'autre ne changera pas.Il est bon de mentionner que lorsque vous sous-définissez la trame de données d'origine, vous pouvez également ajouter la copie en toute sécurité afin d'éviter le
SettingWithCopyWarning
la source