PythonのPandasライブラリを使ってデータを処理していると、「元のデータを変更せずにコピーしたい」「一部だけ加工したい」などの場面がよくあります。
そのような場合に欠かせないのが、DataFrameやSeriesのコピー(複製)です。
Pandasにおけるコピーの方法は一見シンプルに見えますが、表面的なコピー(参照)と完全なコピー(深いコピー)を正しく区別しないと、思わぬバグやデータ破壊を引き起こすことがあります。
このページでは、Pandasでのコピー方法を実例とともに詳しく解説し、安全かつ効率的な使い分けを学べるようにまとめます。
「代入」はコピーではない ― 単なる参照の共有
まず最も重要な点は、以下のような代入はコピーではないということです。
copy_df = df
このコードは、df
のデータを copy_df
にコピーしているように見えますが、実際には同じオブジェクトへの別名(エイリアス)を作っているだけです。
つまり、copy_df
を編集すると、df
も同時に変更されます。
例:参照の共有
import pandas as pd
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
copy_df = df # 実際は「同じオブジェクト」
copy_df.loc[0, 'A'] = 100
print(df) # df も変更されている!
結果
A B
0 100 3
1 2 4
このように、意図せず元のデータを書き換えてしまうリスクがあるため、参照の共有は注意が必要です。
copy()
メソッドによる明示的なコピー
Pandasでは、copy()
メソッドを使うことで明示的にコピーができます。
このとき、次の2種類のコピーが可能です。
◾ deep=True
(デフォルト): 深いコピー(deep copy)
完全な独立コピーを作成します。
元データの値・インデックス・構造のすべてを再帰的に複製するため、編集しても元データには一切影響を与えません。
copy_df = df.copy(deep=True) # 明示的な深いコピー
例
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
copy_df = df.copy() # deep=True がデフォルト
copy_df.loc[0, 'A'] = 100
print(df) # 元の df は変わらない
結果
A B
0 1 3
1 2 4
◾ deep=False
: 浅いコピー(shallow copy)
構造だけを複製し、データ(内部のNumPy配列)は元と共有します。
インデックスやカラムラベルは複製されますが、セルの値を変更すると元にも影響する可能性があるため注意が必要です。
copy_df = df.copy(deep=False)
補足
- 通常はあまり使いません。
- メモリ効率は良いですが、破壊的変更を引き起こすリスクがあります。
copy()
メソッドの構文と意味
df.copy(deep=True)
引数 | 説明 |
---|---|
deep=True | データとインデックスをすべて再帰的にコピー(完全独立) |
deep=False | データ本体は共有。インデックスなどは複製されるが、整合性は保証されない |
コピーの適切な使い分け
シチュエーション | 推奨される方法 | 理由 |
---|---|---|
元のデータを保持したまま加工したい | df.copy(deep=True) | 安全に編集できる |
メモリ節約しつつ元データも編集しない想定 | copy_df = df (参照コピー) | 軽量で高速 |
インデックス構造だけ残し、内容は共有したい場合 | df.copy(deep=False) | 高度な用途に限る(通常は非推奨) |
特定の列・Seriesをコピーする方法
特定の列(DataFrame形式)のコピー
col_copy = df[['A']].copy()
Seriesのコピー
s = df['A'].copy()
このように、列単位やSeries単位でも copy()
を使うことで、元データを壊さずに処理可能になります。
コピーが本当に独立しているか確認するには?
Pythonの組み込み関数 id()
を使うと、オブジェクトが異なるかを確認できます。
print(id(df))
print(id(copy_df)) # 異なれば別物
また、NumPyの .values
に対して id(df.values)
を見ることで、データ部分が共有されているかどうかも判断可能です。
NumPyとの違いと注意点
Pandasは内部でNumPy配列を使っているため、deep=False
ではNumPy配列は参照のままです。
そのため、浅いコピーではセルの値を変更すると元のデータにも影響が及ぶことがあります。
まとめ
コピー方法 | 完全独立 | 元に影響 | 使用頻度 | 備考 |
---|---|---|---|---|
copy_df = df | × | ✓ | 高 | 単なる参照(コピーではない) |
df.copy(deep=True) | ✓ | × | 非常に高 | 安全な方法 |
df.copy(deep=False) | △(一部共有) | △(一部影響) | 低 | 上級者向け |
補足:実務でのベストプラクティス
- 前処理やETL処理などで元データを残したいときは、必ず
df.copy()
を使う - 学習用・検証用のスクリプトでも、元を壊したくない場合は常に明示的コピー
copy_df = df
は速度やメモリ面では有利ですが、バグの温床になりやすいため注意
以上、PythonのPandasでデータコピーをする方法についてでした。
最後までお読みいただき、ありがとうございました。