Copy-on-Write activé par défaut
Pandas 3.0 active Copy-on-Write (CoW) par défaut. Ce mécanisme change fondamentalement la sémantique des opérations de copie : un DataFrame dérivé d'un autre partage la mémoire sous-jacente jusqu'à ce qu'une modification soit effectuée, moment où une copie réelle est créée.
Avant / Après
L'ancien comportement pouvait provoquer des modifications inattendues via des vues partagées. Avec CoW, chaque modification est isolée.
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
# Créer un sous-ensemble
subset = df[['a']]
# AVANT Pandas 3.0 (sans CoW) :
# subset['a'] = 99 # MODIFIE aussi df ! (SettingWithCopyWarning)
# AVEC Pandas 3.0 (CoW activé) :
subset['a'] = 99
print(subset)
# a
# 0 99
# 1 99
# 2 99
print(df)
# a b
# 0 1 4 <- df n'est PAS modifié
# 1 2 5
# 2 3 6
Impact sur les performances et la migration
CoW réduit les copies mémoire inutiles : tant qu'on ne modifie pas, la mémoire est partagée. Les opérations comme df.rename(), df.set_index() ou df.reset_index() ne copient plus les données. Pour migrer, supprimez les appels à .copy() défensifs qui ne sont plus nécessaires.
import pandas as pd
df = pd.DataFrame({'x': range(1_000_000), 'y': range(1_000_000)})
# Ces opérations NE copient PAS les données (CoW)
df2 = df.rename(columns={'x': 'col_x'})
df3 = df.reset_index()
df4 = df[['x']] # pas de copie tant qu'on ne modifie pas
# La copie n'a lieu QUE quand on modifie
df4['x'] = 0 # ici, une copie est déclenchée pour df4
# Migration : supprimez les .copy() défensifs
# Avant : subset = df[['a']].copy() # nécessaire
# Après : subset = df[['a']] # suffisant avec CoW
