CSVファイルを読み込んだあとに、同じ顧客IDや同じ注文番号が何度も出てくることがあります。
そのときに、いきなり重複行を削除してしまうと、本当は残すべき注文データまで消してしまうことがあります。
そこで使うのが、Pandasの duplicated() です。
duplicated() は、重複している行を True / False で確認するためのメソッドです。
drop_duplicates() のように重複を削除する前に、「どの行が重複と判定されているのか」を確認するために使います。
この記事では、duplicated() を使って重複行を安全に確認し、削除・集計・結合に進む前に「どのデータを残すべきか」を判断できるようにします。
- 先に結論
- この記事でわかること
- Pandas DataFrame入門シリーズでの位置づけ
- 1. duplicated()とは何か
- 2. サンプルデータを用意する
- 3. 行全体の重複を確認する
- 4. 重複行だけを抽出する
- 5. duplicated().sum()で重複件数を確認する
- 6. subsetで特定の列だけを基準にする
- 7. keepの違いを理解する
- 8. duplicated()とdrop_duplicates()の違い
- 9. value_counts()やgroupby()との使い分け
- 削除前チェックリスト:重複行を消す前に確認すること
- 11. よくあるミスと注意点
- 12. 前処理の流れの中でduplicated()を使うタイミング
- 13. まとめ
- 次に読みたい関連記事
先に結論
duplicated() は、重複行を削除するメソッドではなく、重複している行を確認するためのメソッドです。
迷ったら、まず次の流れで確認すると安全です。
df.duplicated()で重複の有無を見るdf[df.duplicated(keep=False)]で重複グループ全体を確認するsubsetで「どの列を基準に重複と見るか」を決める- 本当に削除してよいと判断できたら
drop_duplicates()を使う
特に初心者のうちは、重複を見つけることと重複を削除することを分けて考えるのが大切です。
この記事でわかること
この記事では、次の内容を初心者向けに解説します。
duplicated()で重複行を確認する方法True/Falseの意味- 重複行だけを抽出する方法
duplicated().sum()で重複件数を確認する方法subsetで特定の列だけを基準にする方法keep='first'、keep='last'、keep=Falseの違いduplicated()とdrop_duplicates()の違い- 重複行を削除する前に確認すべきポイント
ポイントは、重複を見つけることと、重複を削除することを分けて考えることです。
Pandas DataFrame入門シリーズでの位置づけ
このテーマは、Pandasの前処理の中でも「データ品質チェック」に近い内容です。
基本的な流れとしては、次のように考えると自然です。
- CSVを読み込む
head()、info()、describe()で全体を確認するisnull()で欠損値を確認するduplicated()で重複行を確認する- 必要に応じて
drop_duplicates()で削除する value_counts()、groupby()、pivot_table()などで集計する
つまり、duplicated() は「削除するためのメソッド」というより、削除してよいか判断する前の確認メソッドとして使うのが大切です。
1. duplicated()とは何か
duplicated() は、DataFrameの行が重複しているかどうかを確認するメソッドです。
基本形は次のとおりです。
df.duplicated()
実行すると、各行について True または False が返ります。
| 結果 | 意味 |
|---|---|
False |
その時点では重複扱いされていない行 |
True |
前に同じ行があり、重複と判定された行 |
ここで注意したいのは、duplicated() は重複行を削除しないという点です。
あくまで「この行は重複ですか?」を確認するためのメソッドです。
重複を削除したい場合は、あとで drop_duplicates() を使います。
2. サンプルデータを用意する
ここでは、注文データを例にします。
同じ注文番号が2回出てくる行もあれば、同じ顧客が別の商品を注文している行もあります。
初心者が迷いやすいのは、同じ値があるからといって、必ず削除してよいとは限らない点です。
import pandas as pd
df = pd.DataFrame({
"注文番号": ["A001", "A002", "A003", "A003", "A004", "A005", "A006", "A006", "A007"],
"顧客ID": ["C001", "C002", "C003", "C003", "C001", "C004", "C005", "C005", "C006"],
"氏名": ["佐藤", "鈴木", "田中", "田中", "佐藤", "高橋", "伊藤", "伊藤", "山田"],
"商品": ["ノートPC", "マウス", "キーボード", "キーボード", "モニター", "マウス", "USBメモリ", "USBメモリ", "マウス"],
"金額": [120000, 2500, 8000, 8000, 30000, 2500, 1500, 1500, 2500],
"注文日": ["2026-04-01", "2026-04-02", "2026-04-03", "2026-04-03", "2026-04-05", "2026-04-06", "2026-04-07", "2026-04-07", "2026-04-08"]
})
df
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 |
このデータでは、次のような状態があります。
A003の注文が2回出ているA006の注文が2回出ているC001の顧客は2回出ているが、注文番号と商品が違う佐藤という名前も2回出ているが、同じ人の別注文として残す可能性がある
このように、重複確認では「どの列を基準に重複と見るか」がとても重要です。
3. 行全体の重複を確認する
まずは、行全体が同じかどうかを確認します。
df.duplicated() を使うと、前に同じ行がある場合に True が返ります。
df.duplicated()
| 0 | False |
| 1 | False |
| 2 | False |
| 3 | True |
| 4 | False |
| 5 | False |
| 6 | False |
| 7 | True |
| 8 | False |
この結果だけだと少し見づらいので、元のDataFrameに「重複判定」列を一時的に追加して確認してみましょう。
df_check = df.copy()
df_check["重複判定"] = df_check.duplicated()
df_check
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | 重複判定 | |
|---|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 | False |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 | False |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | False |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 | False |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 | False |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | False |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 | False |
処理前→duplicated()結果→重複行だけ抽出の見方
duplicated() を理解するときは、次の3段階で見ると分かりやすいです。
| 段階 | 確認すること | 使うコード |
|---|---|---|
| 処理前 | 元データに重複候補があるか | df |
| duplicated()結果 | 各行が重複扱いかどうか | df.duplicated() |
| 重複行だけ抽出 | True になった行だけを見る |
df[df.duplicated()] |
この記事では、いきなり削除せず、まずこの流れで「どの行が重複と判定されているか」を確認します。
特に True は「削除する行」と決めつけるのではなく、重複候補として確認すべき行と考えるのが安全です。
True になっている行は、前に同じ内容の行があるため「重複」と判定された行です。
ここで大切なのは、False が「絶対に重複していない」という意味ではないことです。
初期設定では、最初に出てきた行は残す前提で False になります。
| 判定 | 初心者向けの考え方 |
|---|---|
False |
最初に出てきた行、または重複していない行 |
True |
すでに前に同じ行がある行 |
この仕組みは、後で説明する keep='first' と関係しています。
4. 重複行だけを抽出する
重複している行だけを見たい場合は、df.duplicated() の結果を条件として使います。
これは条件抽出と同じ考え方です。
df[df.duplicated()]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
このコードでは、duplicated() が True になった行だけを取り出しています。
つまり、次のような意味です。
df[重複している行だけ]
削除する前に、まずこのように重複行だけを表示して確認すると安全です。
5. duplicated().sum()で重複件数を確認する
重複行が何件あるかだけを知りたい場合は、duplicated().sum() を使います。
df.duplicated().sum()
duplicated() は True / False を返します。
Pandasでは、True は 1、False は 0 のように数えられるため、.sum() を付けると True の数、つまり重複と判定された行数を確認できます。
| コード | 意味 |
|---|---|
df.duplicated() |
各行が重複かどうかを確認する |
df.duplicated().sum() |
重複と判定された行数を数える |
ただし、この件数は「削除すべき件数」とは限りません。
まずは中身を確認してから判断しましょう。
重複グループ全体を確認したい場合は、後で説明する keep=False を使うと、最初の行も含めてまとめて確認できます。
6. subsetで特定の列だけを基準にする
ここまでの duplicated() は、行全体が同じかどうかを見ていました。
しかし実務では、行全体ではなく、特定の列だけを基準に重複を確認したいことが多いです。
たとえば、注文データなら次のように考えられます。
| 見たいこと | 基準にする列 |
|---|---|
| 同じ注文が重複していないか | 注文番号 |
| 同じ顧客が複数回出ているか | 顧客ID |
| 同じ顧客の同じ注文が重複していないか | 顧客ID と 注文番号 |
このようなときに使うのが subset です。
注文番号だけを基準に重複を確認する
注文番号が同じなら、同じ注文が二重に入っている可能性があります。
そこで、subset=["注文番号"] を指定します。
df_order_check = df.copy()
df_order_check["注文番号の重複"] = df_order_check.duplicated(subset=["注文番号"])
df_order_check[["注文番号", "顧客ID", "氏名", "商品", "金額", "注文日", "注文番号の重複"]]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | 注文番号の重複 | |
|---|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 | False |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 | False |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | False |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 | False |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 | False |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | False |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 | False |
このように、subset を使うと「行全体」ではなく「指定した列」だけを基準に重複を確認できます。
今回の例では、注文番号 が同じ行を重複候補として確認できます。
顧客IDだけを見ると、削除してはいけないデータまで重複に見えることがある
次に、顧客ID だけを基準にしてみます。
df_customer_check = df.copy()
df_customer_check["顧客IDの重複"] = df_customer_check.duplicated(subset=["顧客ID"], keep=False)
df_customer_check[["注文番号", "顧客ID", "氏名", "商品", "金額", "注文日", "顧客IDの重複"]]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | 顧客IDの重複 | |
|---|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 | True |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 | False |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 | True |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 | False |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 | False |
C001 は2回出てきますが、注文番号も商品も違います。
これは同じ顧客が別の商品を注文しているだけかもしれません。
そのため、顧客ID が重複しているからといって、すぐ削除するのは危険です。
重複確認では、次のように考えることが大切です。
| 状況 | 判断 |
|---|---|
| 同じ注文番号が2回ある | 二重登録の可能性があるため確認する |
| 同じ顧客IDが2回ある | 同じ顧客の複数注文かもしれない |
| 同じ氏名が2回ある | 同姓同名や同じ顧客の別注文かもしれない |
| 行全体が完全に同じ | 重複登録の可能性が高い |
subset は便利ですが、何を基準にするかを間違えると、必要なデータまで削除してしまうことがあります。
顧客IDと注文番号の組み合わせで確認する
より安全に確認したい場合は、複数列を subset に指定します。
たとえば、同じ顧客IDで、同じ注文番号の行があるかを確認してみます。
df_pair_check = df.copy()
df_pair_check["顧客IDと注文番号の重複"] = df_pair_check.duplicated(subset=["顧客ID", "注文番号"], keep=False)
df_pair_check[["注文番号", "顧客ID", "氏名", "商品", "金額", "注文日", "顧客IDと注文番号の重複"]]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | 顧客IDと注文番号の重複 | |
|---|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 | False |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 | False |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 | True |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 | False |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 | False |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 | True |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 | False |
このように、subset=["顧客ID", "注文番号"] とすると、2つの列の組み合わせで重複を確認できます。
初心者のうちは、次の順番で考えると迷いにくいです。
- まず行全体の重複を見る
- 次に、注文番号やIDなど、重複の基準になりそうな列を見る
- 必要なら複数列の組み合わせで確認する
- 中身を見てから削除するか判断する
7. keepの違いを理解する
duplicated() で初心者が迷いやすいのが、keep です。
keep は、重複しているデータのうち、どの行を False として残す扱いにするかを決める引数です。
| 指定 | 意味 |
|---|---|
keep='first' |
最初の行を False にし、2回目以降を True にする |
keep='last' |
最後の行を False にし、それより前を True にする |
keep=False |
重複している行をすべて True にする |
初期設定は keep='first' です。
同じデータでkeepの3パターンを比較する
注文番号を基準にして、keep='first'、keep='last'、keep=False の違いを見てみましょう。
df_keep = df.copy()
df_keep["keep_first"] = df_keep.duplicated(subset=["注文番号"], keep="first")
df_keep["keep_last"] = df_keep.duplicated(subset=["注文番号"], keep="last")
df_keep["keep_false"] = df_keep.duplicated(subset=["注文番号"], keep=False)
df_keep[["注文番号", "顧客ID", "氏名", "商品", "keep_first", "keep_last", "keep_false"]]
| 注文番号 | 顧客ID | 氏名 | 商品 | keep_first | keep_last | keep_false | |
|---|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | False | False | False |
| 1 | A002 | C002 | 鈴木 | マウス | False | False | False |
| 2 | A003 | C003 | 田中 | キーボード | False | True | True |
| 3 | A003 | C003 | 田中 | キーボード | True | False | True |
| 4 | A004 | C001 | 佐藤 | モニター | False | False | False |
| 5 | A005 | C004 | 高橋 | マウス | False | False | False |
| 6 | A006 | C005 | 伊藤 | USBメモリ | False | True | True |
| 7 | A006 | C005 | 伊藤 | USBメモリ | True | False | True |
| 8 | A007 | C006 | 山田 | マウス | False | False | False |
結果を見ると、同じ注文番号でも keep の指定によって True になる行が変わることが分かります。
初心者におすすめなのは、重複グループ全体を見たいときに keep=False を使うことです。
df[df.duplicated(subset=["注文番号"], keep=False)]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
keep=False を使うと、重複している注文番号の行をまとめて確認できます。
削除する前に、
- どちらを残すべきか
- 本当に完全な二重登録なのか
- 金額や注文日が違っていないか
を確認しやすくなります。
8. duplicated()とdrop_duplicates()の違い
duplicated() とよく似た名前のメソッドに、drop_duplicates() があります。
この2つは役割が違います。
| メソッド | 役割 | 使う場面 |
|---|---|---|
duplicated() |
重複している行を True / False で確認する |
削除前に確認したいとき |
drop_duplicates() |
重複行を削除したDataFrameを返す | 確認後に削除したいとき |
この記事の中心は、duplicated() による確認です。
drop_duplicates() は、重複を確認したあとに必要なら使います。
削除する前に、まず確認する
たとえば、注文番号が重複している行を確認するなら、まず次のようにします。
df[df.duplicated(subset=["注文番号"], keep=False)]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
中身を確認して、本当に削除してよいと判断できたら、次に drop_duplicates() を検討します。
df.drop_duplicates(subset=["注文番号"], keep="first")
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 |
| 1 | A002 | C002 | 鈴木 | マウス | 2500 | 2026-04-02 |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 |
| 5 | A005 | C004 | 高橋 | マウス | 2500 | 2026-04-06 |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 8 | A007 | C006 | 山田 | マウス | 2500 | 2026-04-08 |
ただし、この記事では drop_duplicates() の詳しい削除パターンには深入りしません。
詳しく学ぶ場合は、重複削除を扱う記事で確認するのがおすすめです。
大切なのは、次の順番です。
duplicated()で重複を確認するkeep=Falseなどで重複グループ全体を見る- 削除してよいか判断する
- 必要な場合だけ
drop_duplicates()を使う
9. value_counts()やgroupby()との使い分け
重複確認では、value_counts() や groupby() も使えます。
ただし、それぞれ得意なことが少し違います。
| 方法 | 得意なこと |
|---|---|
duplicated() |
どの行が重複しているか確認する |
value_counts() |
列ごとの値が何回出ているか確認する |
groupby().size() |
グループごとの件数を確認する |
drop_duplicates() |
重複行を削除する |
たとえば、注文番号ごとの出現回数を見たいだけなら、value_counts() が便利です。
df["注文番号"].value_counts()
| count | |
|---|---|
| A003 | 2 |
| A006 | 2 |
| A001 | 1 |
| A002 | 1 |
| A004 | 1 |
| A005 | 1 |
| A007 | 1 |
groupby().size() を使っても、注文番号ごとの件数を確認できます。
df.groupby("注文番号").size()
| A001 | 1 |
| A002 | 1 |
| A003 | 2 |
| A004 | 1 |
| A005 | 1 |
| A006 | 2 |
| A007 | 1 |
ただし、value_counts() や groupby().size() は「何件あるか」を見るのに向いています。
一方で、duplicated() は「どの行が重複として扱われるか」を見るのに向いています。
行そのものを確認したいときは、duplicated() を使うと分かりやすいです。
削除前チェックリスト:重複行を消す前に確認すること
duplicated() で重複が見つかっても、すぐに削除する必要はありません。
削除前には、次の表で確認すると安全です。
| 確認すること | 見るポイント | 判断の例 |
|---|---|---|
| 行全体が完全に同じか | すべての列が同じか | 完全一致なら二重登録の可能性が高い |
| IDや注文番号だけが同じか | 商品・日付・金額が違わないか | 同じ顧客の別注文なら残す |
| どの列を基準にするか | subset に指定する列 |
注文番号、顧客ID、顧客ID+注文番号など |
| 重複グループ全体を見たか | keep=False で確認したか |
最初の行も含めて確認できる |
| 削除後の影響はあるか | 集計や売上合計が変わるか | 集計前に確認しておく |
このチェックを入れることで、drop_duplicates() で必要なデータまで消してしまうリスクを減らせます。
11. よくあるミスと注意点
ここでは、初心者がつまずきやすいポイントを整理します。
ミス1:duplicated()で重複が削除されると思ってしまう
duplicated() は重複を削除しません。
True / False で確認するだけです。
# duplicated()は削除ではなく、True / False の確認です
df.duplicated()
| 0 | False |
| 1 | False |
| 2 | False |
| 3 | True |
| 4 | False |
| 5 | False |
| 6 | False |
| 7 | True |
| 8 | False |
削除したい場合は drop_duplicates() を使います。
ただし、削除する前に必ず中身を確認しましょう。
ミス2:Trueを「残す行」だと思ってしまう
duplicated() の True は、「重複と判定された行」という意味です。
「残す行」という意味ではありません。
| 結果 | 意味 |
|---|---|
False |
最初に出てきた行、または重複していない行 |
True |
重複と判定された行 |
特に初期設定の keep='first' では、最初の行は False になります。
ミス3:名前だけで重複削除しようとする
同じ名前があるからといって、同じ人とは限りません。
また、同じ人でも別の商品を注文している可能性があります。
名前だけで確認すると、削除してはいけないデータまで重複に見えることがあります。
df[df.duplicated(subset=["氏名"], keep=False)]
| 注文番号 | 顧客ID | 氏名 | 商品 | 金額 | 注文日 | |
|---|---|---|---|---|---|---|
| 0 | A001 | C001 | 佐藤 | ノートPC | 120000 | 2026-04-01 |
| 2 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 3 | A003 | C003 | 田中 | キーボード | 8000 | 2026-04-03 |
| 4 | A004 | C001 | 佐藤 | モニター | 30000 | 2026-04-05 |
| 6 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
| 7 | A006 | C005 | 伊藤 | USBメモリ | 1500 | 2026-04-07 |
この例では、佐藤 さんが2回出ています。
しかし、注文番号と商品が違うため、単純に削除してよいとは言えません。
重複確認では、名前だけではなく、顧客ID、注文番号、注文日 なども合わせて確認しましょう。
ミス4:subsetを指定せずに「重複がない」と判断してしまう
subset を指定しない場合、行全体が同じかどうかを見ます。
そのため、注文番号は同じでも、どこか1列だけ違うと、行全体としては重複にならないことがあります。
「注文番号だけを見たい」「顧客IDだけを見たい」という目的がある場合は、subset を使いましょう。
ミス5:重複は必ず悪いデータだと思ってしまう
重複しているように見えるデータでも、実際には意味のあるデータの場合があります。
| 重複して見える例 | 削除してよいか |
|---|---|
| 同じ顧客IDが複数回出る | 同じ顧客の複数注文なら残す |
| 同じ商品名が複数回出る | 商品別集計では普通にありえる |
| 同じ注文番号が完全に同じ内容で2回出る | 二重登録の可能性があるため確認する |
| 行全体が完全に同じ | 重複登録の可能性が高い |
重複確認の目的は、機械的に消すことではありません。
「残すべきか、削除すべきか」を判断することです。
12. 前処理の流れの中でduplicated()を使うタイミング
duplicated() は、Pandasの前処理の中で早めに使うと便利です。
おすすめの流れは次のとおりです。
| 順番 | 確認内容 | 使うメソッド例 |
|---|---|---|
| 1 | データの先頭を見る | head() |
| 2 | 列名・型・欠損数を見る | info() |
| 3 | 統計量を見る | describe() |
| 4 | 欠損値を確認する | isnull() |
| 5 | 重複行を確認する | duplicated() |
| 6 | 必要に応じて重複を削除する | drop_duplicates() |
| 7 | 件数やグループごとに確認する | value_counts()、groupby() |
| 8 | 表形式に集計する | pivot_table() |
重複確認をせずに集計へ進むと、件数や合計金額が二重に数えられることがあります。
そのため、集計や可視化の前に、duplicated() で重複の有無を確認しておくと安心です。
13. まとめ
この記事では、Pandasの duplicated() を使って重複行を確認する方法を解説しました。
重要なポイントを整理します。
duplicated()は、重複行をTrue/Falseで確認するメソッドduplicated()は重複を削除しない- 重複行だけを見たいときは
df[df.duplicated()]を使う - 重複件数を見たいときは
df.duplicated().sum()を使う - 特定列を基準にしたいときは
subsetを使う keep='first'、keep='last'、keep=Falseで重複判定のされ方が変わる- 重複を削除したいときは、確認後に
drop_duplicates()を使う - 重複は必ずしも悪いデータではないため、削除前に中身を確認する
初心者のうちは、次の順番で考えるのがおすすめです。
- まず
duplicated()で重複を確認する keep=Falseで重複グループ全体を見るsubsetで重複の基準列を決める- 削除してよいと判断できたら
drop_duplicates()に進む
duplicated() を使えるようになると、データを削除する前に安全に確認できるようになります。
次に読みたい関連記事
この記事とあわせて読むと、Pandasの前処理の流れがつながりやすくなります。
Pandas DataFrame入門|作り方・基本操作をわかりやすく解説
DataFrameの基本構造を確認したい方におすすめです。Pandas info()とdescribe()の違い|欠損値・型・統計量の見方を例で解説
重複確認の前に、データ全体の型や欠損数を確認したいときに役立ちます。欠損値を可視化して攻略!Pandas isnullとヒートマップ活用術
重複確認とあわせて、欠損値も確認したいときにおすすめです。Pandas dropna()・drop_duplicates()の使い方|欠損/重複の削除とdrop()基本
重複を確認したあと、実際に削除する方法を学びたい場合はこちらです。pandas value_counts()の使い方|件数集計・割合表示・欠損値の数え方を解説
値の出現回数や表記ゆれを確認したいときに役立ちます。Pandas groupby×aggの使い方|基本の集計とaggの書き方を例で解説
重複確認後に、グループごとの集計へ進みたい方におすすめです。Pandas pivotとpivot_tableの違い|重複データ対応と集計方法
重複データがあるときに、pivotとpivot_tableをどう使い分けるかを学べます。pandas reset_index()の使い方|インデックスを振り直す・drop=Trueを初心者向けに解説
重複削除後にインデックスを整えたいときに役立ちます。Pandas concat完全ガイド|複数CSVからDataFrameを縦横結合する方法
複数データを結合したあとに重複が出る場面を理解しやすくなります。
pandas duplicated()は何をするメソッドですか?
duplicated() は、DataFrameの行が重複しているかどうかを True / False で確認するメソッドです。
重複を削除するのではなく、削除前にどの行が重複と判定されるかを確認するために使います。
duplicated()とdrop_duplicates()の違いは何ですか?
duplicated() は重複行を True / False で確認します。drop_duplicates() は重複行を削除したDataFrameを返します。
削除前の確認には duplicated()、削除には drop_duplicates() と考えると分かりやすいです。
重複行だけを表示するにはどうすればよいですか?
次のように書きます。df[df.duplicated()]
特定の列を基準にしたい場合は、次のように subset を指定します。df[df.duplicated(subset=["注文番号"], keep=False)]
keep=False を使うと、重複しているグループ全体を確認しやすくなります。
duplicated().sum()は何を数えていますか?
keep=False を使うと、重複しているグループ全体を確認しやすくなります。
duplicated().sum()は何を数えていますか?
duplicated() で True になった行数を数えています。
つまり、重複と判定された行が何件あるかを確認できます。
ただし、この件数は「削除すべき件数」とは限りません。削除前に、実際の行の中身を確認しましょう。
subsetは何のために使いますか?
subset は、重複判定に使う列を指定するための引数です。
たとえば、注文番号だけを基準にしたい場合は次のように書きます。df.duplicated(subset=["注文番号"])
行全体ではなく、特定列だけを基準に重複確認したいときに使います。
keep=’first’、keep=’last’、keep=Falseの違いは何ですか?
keep='first' は最初の行を残す扱いにし、2回目以降を True にします。keep='last' は最後の行を残す扱いにし、それより前を True にします。keep=False は、重複している行をすべて True にします。
重複グループ全体を確認したいときは、keep=False が便利です。
重複行は必ず削除したほうがよいですか?
必ず削除する必要はありません。
同じ顧客が複数回注文している場合や、同じ商品が複数回売れている場合は、意味のあるデータです。
削除する前に、何を基準に重複と見るのかを確認しましょう。
value_counts()とduplicated()はどう使い分けますか?
value_counts() は、値が何回出ているかを確認するのに向いています。duplicated() は、どの行が重複として判定されるかを確認するのに向いています。
件数を見たいときは value_counts()、行を確認したいときは duplicated() と考えると分かりやすいです。
コメント