データ分析のプロセスにおいて、最初に行うべき最も重要な作業の一つがデータのクリーニングです。
データセット内に重複した行が存在すると、平均値や合計値の算出が不正確になり、結果として誤ったビジネス判断を導くリスクがあります。
Pythonのデータ分析ライブラリであるPandasには、こうした重複データを簡単かつ柔軟に処理するためのdrop_duplicatesメソッドが用意されています。
本記事では、drop_duplicatesの基本的な使い方から、実務で役立つ詳細なオプションの指定方法までを具体的に解説します。
効率的なデータクレンジングの手法を学び、正確な分析基盤を構築するためのスキルを身につけていきましょう。
Pandasのdrop_duplicatesメソッドの基本
Pandasのdrop_duplicatesは、DataFrameから重複した行を特定して削除するための非常に強力なメソッドです。
デフォルトの設定では、すべての列の値が完全に一致する行を探し、最初に出現した行を保持してそれ以降の重複を削除します。
まずは、最もシンプルな形での使用例を確認してみましょう。
import pandas as pd
# サンプルデータの作成
data = {
'user_id': [101, 102, 101, 103, 102],
'product': ['Apple', 'Orange', 'Apple', 'Banana', 'Orange'],
'price': [150, 200, 150, 120, 200]
}
df = pd.DataFrame(data)
# 重複した行を削除
df_unique = df.drop_duplicates()
print(df_unique)
user_id product price
0 101 Apple 150
1 102 Orange 200
3 103 Banana 120
この例では、インデックス2と4の行がそれぞれ0と1の行と完全に一致していたため、削除されました。
元のDataFrameは変更されず、新しいDataFrameが返される点に注目してください。
drop_duplicatesの主要な引数と役割
実務ではすべての列が一致する場合だけでなく、特定の列を基準に重複を判定したいケースが多々あります。
drop_duplicatesには、挙動を細かく制御するための引数がいくつか用意されています。
| 引数名 | デフォルト値 | 説明 |
|---|---|---|
subset | None | 重複判定の対象とする列名のリストを指定します。 |
keep | ‘first’ | どの重複行を残すか(’first’, ‘last’, False)を指定します。 |
inplace | False | Trueに設定すると、元のオブジェクトを直接書き換えます。 |
ignore_index | False | Trueに設定すると、削除後のインデックスを0から振り直します。 |
これらの引数を適切に組み合わせることで、複雑なデータクレンジング要件に対応できるようになります。
subset引数:特定の列を基準にする
特定の列に注目して重複を排除したい場合は、subset引数を使用します。
例えば、「ユーザーIDが重複しているデータは、他の列の値が違っていても削除したい」という場合に有効です。
# user_id列のみを基準に重複を削除
df_subset = df.drop_duplicates(subset=['user_id'])
print(df_subset)
user_id product price
0 101 Apple 150
1 102 Orange 200
3 103 Banana 120
subsetには複数の列をリスト形式で渡すことも可能です。
「ユーザーIDと商品名の組み合わせが同じデータ」のみを削除するといった、柔軟な条件設定が行えます。
keep引数:残す行の選択
重複が見つかった際、どのデータを正とするかをkeep引数で決定します。
デフォルトの'first'は最初に見つかった行を残しますが、'last'を指定すると最後に見つかった行を保持します。
# 重複したデータのうち、最後に出現したもの(last)を残す
df_last = df.drop_duplicates(subset=['user_id'], keep='last')
print(df_last)
user_id product price
2 101 Apple 150
3 103 Banana 120
4 102 Orange 200
また、keep=Falseを指定すると、重複している行すべてを削除することができます。
これは、一意であるべきデータに重複が発生している場合に、エラーデータとして一括排除したい時に役立ちます。
重複データの確認とカウント
削除を行う前に、どの程度の重複が存在するかを確認しておくことは、データ分析の品質管理において重要です。
これにはduplicatedメソッドを使用します。
duplicatedは各行が重複しているかどうかをブール値(True/False)で返します。
# 重複している行を特定(True/FalseのSeriesが返る)
duplicate_flags = df.duplicated()
# 重複している行数を確認
duplicate_count = df.duplicated().sum()
print(f"重複行数: {duplicate_count}")
print(df[duplicate_flags])
重複行数: 2
user_id product price
2 101 Apple 150
4 102 Orange 200
このように、削除を実行する前に検算を行う習慣をつけると、予期せぬデータの消失を防ぐことができます。
効率的なデータ処理と注意点
大量のデータを扱う際、効率的に重複を削除するためにはいくつかのテクニックがあります。
インデックスのリセット
drop_duplicatesを実行すると、元の行番号(インデックス)が飛び飛びの状態になります。
その後の処理でループを回したり、特定の行を参照したりする場合に不都合が生じることがあります。
ignore_index=Trueを指定することで、削除と同時に綺麗な連番に振り直すことができます。
# 重複を削除し、インデックスを振り直す
df_reset = df.drop_duplicates(ignore_index=True)
print(df_reset)
user_id product price
0 101 Apple 150
1 102 Orange 200
2 103 Banana 120
ソートと組み合わせた最新データの抽出
実務で非常によく使われるテクニックが、「日付でソートしてから重複を削除し、各グループの最新レコードを取得する」という手法です。
例えば、同じ顧客が何度も購入している履歴データから、各顧客の「最後の購入履歴」だけを抽出する場合です。
# 日付順にソート(昇順)
df_sorted = df_history.sort_values('purchase_date')
# ユーザーIDで重複を削除し、最後の行(最新日付)を残す
latest_purchases = df_sorted.drop_duplicates(subset=['customer_id'], keep='last')
このように、sort_valuesとdrop_duplicatesを組み合わせることで、複雑な条件でのデータ抽出が簡潔に記述できます。
欠損値(NaN)が含まれる場合の挙動
Pandasにおいて、欠損値(NaN)は重複判定の際、一つの「値」として扱われます。
つまり、特定の列に複数のNaNがある場合、それらは互いに重複していると見なされます。
もし、欠損値がある行を重複削除の対象から外したい、あるいは先に除外したい場合は、dropnaメソッドを併用することを検討してください。
データの欠損が何を意味するのかを事前に定義しておくことが、正しいクリーニングの第一歩です。
大規模データにおけるパフォーマンスの考慮
数百万件規模のDataFrameに対してdrop_duplicatesを適用する場合、メモリ使用量と実行時間に注意が必要です。
不必要な列をあらかじめdropで削除してから重複チェックを行うと、処理速度が向上する場合があります。
また、メモリに余裕がない場合はinplace=Trueを検討しがちですが、Pandasの内部的にはコピーが作成されることが多いため、劇的な改善には繋がらない場合もあります。
最新のPandas(2.0以降)では、バックエンドの最適化が進んでいますが、処理対象のデータ型(例えば文字列よりも整数型の方が速い)を意識することも大切です。
まとめ
Pandasのdrop_duplicatesは、データクレンジングにおける必須のツールです。
基本的な使い方だけでなく、subsetによる列指定やkeepによる保持条件の制御をマスターすることで、分析の精度は格段に向上します。
特に、sort_valuesと組み合わせた最新情報の抽出は、実務で頻出するパターンですので、ぜひ覚えておきましょう。
データに重複が残ったまま分析を進めると、最終的なアウトプットの信頼性が損なわれてしまいます。
今回解説したテクニックを活用して、常に清潔で信頼性の高いデータセットを維持するよう心がけてください。
PythonとPandasを使いこなすことで、煩雑なデータ整理作業を効率化し、より本質的なデータ分析の仕事に集中できるようになるはずです。
