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.

python
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.

python
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

Sources