🐼

Pandas 3.0ではCopy-on-Writeがデフォルトかつ唯一のモードになる

に公開

概要

  • Copy-on-Write (CoW) はPandas 2.0で導入された、DataFrameやSeriesのオブジェクトをより予測可能に扱うための新しい方法です。
  • デフォルトでは無効ですが、3.0でデフォルトかつ唯一のモードになる予定です。
  • 有効にするにはpd.options.mode.copy_on_write = Trueを設定します。
  • 一部のコードは動作しなくなる可能性があります。
  • pd.options.mode.copy_on_write = "warn"を設定することで、CoWによって動作が変わる操作に対して警告を表示させることができます。 ​
  • 詳しくは公式ドキュメントを参照してください。

メリット

意図しない副作用の防止

  • 従来Pandasでは、あるDataFrameから別のDataFrameを作成した際(スライシングなど)、それが元のデータの「ビュー(参照)」なのか「コピー」なのかが曖昧な場合がありました。
  • ビューに対して変更を加えると、意図せず元のデータも変更されてしまうことがあり、SettingWithCopyWarningという警告の原因になっていました。
  • CoWを有効にすると、DataFrameやSeriesに対する操作(インデックス指定、メソッド呼び出しなど)は常に新しいオブジェクト(コピー)を返すようになります(ただし後述するようにコピーは遅延実行されます)。これにより、元のオブジェクトが予期せず変更されることを防ぎます。
  • SettingWithCopyWarningの発生は大幅に減少、またはなくなります。特に、連鎖代入(chained assignment) (df[...][...] = ...)による意図しない挙動が抑制されます。

コードの予測可能性向上

オブジェクトが変更されるのは、そのオブジェクト自身に対する代入操作が行われたときのみに限定されます。これにより、コードの動作が理解しやすくなります。

パフォーマンス

オブジェクトのコピーは、そのオブジェクトが実際に変更されるまで遅延されます。読み取り操作が多いワークフローでは、不要なデータコピーが発生せずパフォーマンスが向上する可能性があります。

注意点

連鎖代入(chained assignment)は機能しなくなります。

df = pd.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]})
df["foo"][df["bar"] > 5] = 100

代わりにlocを使用することが推奨されています。

df.loc[df["bar"] > 5, "foo"] = 100

CoWを有効にすると、従来の「ビュー」への書き込みに依存していたコードは動作しなくなる可能性があります。例えば、スライスで得たビューに対して値を代入しても、元のDataFrameは変更されません。

df = pd.DataFrame({"foo": [1, 2, 3], "bar": [4, 5, 6]})
subset = df["foo"]
subset.iloc[0] = 100
df

subsetを変更してもdfは変更されません。

   foo  bar
0    1    4
1    2    5
2    3    6

まとめ

  • Copy-on-Writeによりデータ操作の安全性と予測可能性を向上させることができます。
  • デフォルトでは無効ですが、3.0でデフォルトかつ唯一のモードになる予定です。
  • 一部のコードは動作しなくなる可能性があります。

Discussion