Pandas 重複データ処理
重複データはデータ分析でよく発生する問題であり、統計結果の正確性に影響を与える可能性があります。Pandas は重複データを検出・処理するための完全な機能を提供しています。
重複データの検出
duplicated メソッド
例
import pandas as pd
# 重複行を含む DataFrame を作成
df = pd.DataFrame({
"名前": ["田中", "佐藤", "鈴木", "田中", "佐藤", "高橋"],
"年齢": [25, 30, 28, 25, 30, 35],
"都市": ["北京", "上海", "広州", "北京", "深セン", "北京"]
})
print("元のデータ:")
print(df)
print()
# 重複行を検出(デフォルトでは最初の行からマーク、keep='first')
print("重複行の検出:")
print(df.duplicated())
print()
# 重複行の数を集計
print(f"重複行数: {df.duplicated().sum()}")
print()
# 特定の列の重複を検出
print("「名前」列で重複を検出:")
print(df.duplicated(subset=["名前"]))
# 重複行を含む DataFrame を作成
df = pd.DataFrame({
"名前": ["田中", "佐藤", "鈴木", "田中", "佐藤", "高橋"],
"年齢": [25, 30, 28, 25, 30, 35],
"都市": ["北京", "上海", "広州", "北京", "深セン", "北京"]
})
print("元のデータ:")
print(df)
print()
# 重複行を検出(デフォルトでは最初の行からマーク、keep='first')
print("重複行の検出:")
print(df.duplicated())
print()
# 重複行の数を集計
print(f"重複行数: {df.duplicated().sum()}")
print()
# 特定の列の重複を検出
print("「名前」列で重複を検出:")
print(df.duplicated(subset=["名前"]))
keep パラメータ
例
import pandas as pd
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"年齢": [25, 30, 25, 28, 30]
})
print("元のデータ:")
print(df)
print()
# keep='first':最初に出現した行を保持(デフォルト)
print("keep='first'(デフォルト):")
print(df.duplicated(keep="first"))
print()
# keep='last':最後に出現した行を保持
print("keep='last':")
print(df.duplicated(keep="last"))
print()
# keep=False:すべての重複をマーク(何も保持しない)
print("keep=False(すべての重複をマーク):")
print(df.duplicated(keep=False))
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"年齢": [25, 30, 25, 28, 30]
})
print("元のデータ:")
print(df)
print()
# keep='first':最初に出現した行を保持(デフォルト)
print("keep='first'(デフォルト):")
print(df.duplicated(keep="first"))
print()
# keep='last':最後に出現した行を保持
print("keep='last':")
print(df.duplicated(keep="last"))
print()
# keep=False:すべての重複をマーク(何も保持しない)
print("keep=False(すべての重複をマーク):")
print(df.duplicated(keep=False))
重複データの削除
drop_duplicates の基本的な使い方
例
import pandas as pd
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"年齢": [25, 30, 25, 28, 30],
"都市": ["北京", "上海", "北京", "広州", "深セン"]
})
print("元のデータ:")
print(df)
print()
# 重複行を削除(デフォルトでは最初の行を保持)
print("重複行の削除(最初の行を保持):")
print(df.drop_duplicates())
print()
# 最後の行を保持
print("重複行の削除(最後の行を保持):")
print(df.drop_duplicates(keep="last"))
print()
# 重複行を1つも保持しない
print("重複行をすべて削除:")
print(df.drop_duplicates(keep=False))
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"年齢": [25, 30, 25, 28, 30],
"都市": ["北京", "上海", "北京", "広州", "深セン"]
})
print("元のデータ:")
print(df)
print()
# 重複行を削除(デフォルトでは最初の行を保持)
print("重複行の削除(最初の行を保持):")
print(df.drop_duplicates())
print()
# 最後の行を保持
print("重複行の削除(最後の行を保持):")
print(df.drop_duplicates(keep="last"))
print()
# 重複行を1つも保持しない
print("重複行をすべて削除:")
print(df.drop_duplicates(keep=False))
列を指定して重複を削除
例
import pandas as pd
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木"],
"年齢": [25, 30, 35, 28],
"都市": ["北京", "上海", "北京", "広州"]
})
print("元のデータ:")
print(df)
print()
# 単一の列で重複を除去
print("「名前」列で重複を除去:")
print(df.drop_duplicates(subset=["名前"]))
print()
# 複数の列の組み合わせで重複を除去
print("「名前」+「都市」の組み合わせで重複を除去:")
print(df.drop_duplicates(subset=["名前", "都市"]))
print()
# 特定の列の値が最大の行を保持
print("「名前」でグループ化し、年齢が最大のものを保持:")
print(df.sort_values("年齢", ascending=False).drop_duplicates(subset=["名前"], keep="first"))
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木"],
"年齢": [25, 30, 35, 28],
"都市": ["北京", "上海", "北京", "広州"]
})
print("元のデータ:")
print(df)
print()
# 単一の列で重複を除去
print("「名前」列で重複を除去:")
print(df.drop_duplicates(subset=["名前"]))
print()
# 複数の列の組み合わせで重複を除去
print("「名前」+「都市」の組み合わせで重複を除去:")
print(df.drop_duplicates(subset=["名前", "都市"]))
print()
# 特定の列の値が最大の行を保持
print("「名前」でグループ化し、年齢が最大のものを保持:")
print(df.sort_values("年齢", ascending=False).drop_duplicates(subset=["名前"], keep="first"))
実践:データクリーニング
総合事例
例
import pandas as pd
import numpy as np
# 模擬注文データを作成(重複を含む)
orders = pd.DataFrame({
"注文番号": ["O001", "O002", "O001", "O003", "O002", "O004"],
"顧客ID": ["C001", "C002", "C001", "C003", "C002", "C004"],
"商品": ["iPhone", "MacBook", "iPhone", "iPad", "AirPods", "Apple Watch"],
"金額": [8000, 12000, 8000, 5000, 1500, 3000],
"日付": ["2024-01-01", "2024-01-02", "2024-01-01", "2024-01-03", "2024-01-02", "2024-01-04"]
})
print("元の注文データ:")
print(orders)
print()
# 1. 重複注文を検出
print("重複注文の検出:")
duplicates = orders[orders.duplicated(subset=["注文番号"], keep=False)]
print(duplicates)
print()
# 2. 完全に重複した注文を削除
orders_clean = orders.drop_duplicates()
print("完全な重複を削除後:")
print(f"元の {len(orders)} 行 -> {len(orders_clean)} 行")
print()
# 3. 注文番号で重複を除去し、最新のものを保持
# 最後のレコードが最新であると仮定
orders_clean = orders.sort_values("日付").drop_duplicates(
subset=["注文番号"],
keep="last"
).sort_index()
print("注文番号で重複を除去(最新を保持):")
print(orders_clean)
import numpy as np
# 模擬注文データを作成(重複を含む)
orders = pd.DataFrame({
"注文番号": ["O001", "O002", "O001", "O003", "O002", "O004"],
"顧客ID": ["C001", "C002", "C001", "C003", "C002", "C004"],
"商品": ["iPhone", "MacBook", "iPhone", "iPad", "AirPods", "Apple Watch"],
"金額": [8000, 12000, 8000, 5000, 1500, 3000],
"日付": ["2024-01-01", "2024-01-02", "2024-01-01", "2024-01-03", "2024-01-02", "2024-01-04"]
})
print("元の注文データ:")
print(orders)
print()
# 1. 重複注文を検出
print("重複注文の検出:")
duplicates = orders[orders.duplicated(subset=["注文番号"], keep=False)]
print(duplicates)
print()
# 2. 完全に重複した注文を削除
orders_clean = orders.drop_duplicates()
print("完全な重複を削除後:")
print(f"元の {len(orders)} 行 -> {len(orders_clean)} 行")
print()
# 3. 注文番号で重複を除去し、最新のものを保持
# 最後のレコードが最新であると仮定
orders_clean = orders.sort_values("日付").drop_duplicates(
subset=["注文番号"],
keep="last"
).sort_index()
print("注文番号で重複を除去(最新を保持):")
print(orders_clean)
高度な使い方
グループごとに特定の行を保持
例
import pandas as pd
df = pd.DataFrame({
"顧客": ["A", "A", "A", "B", "B", "B"],
"月": ["01", "02", "03", "01", "02", "03"],
"消費額": [100, 200, 150, 300, 250, 280]
})
print("元のデータ:")
print(df)
print()
# 各顧客の消費額が最も高い月を保持
print("各顧客の消費額が最も高い月:")
result = df.sort_values("消費額", ascending=False).drop_duplicates(
subset=["顧客"],
keep="first"
).sort_values("顧客")
print(result)
print()
# 各顧客の最初のレコードを保持(月順)
print("各顧客の最初のレコード:")
result = df.sort_values("月").drop_duplicates(
subset=["顧客"],
keep="first"
)
print(result)
df = pd.DataFrame({
"顧客": ["A", "A", "A", "B", "B", "B"],
"月": ["01", "02", "03", "01", "02", "03"],
"消費額": [100, 200, 150, 300, 250, 280]
})
print("元のデータ:")
print(df)
print()
# 各顧客の消費額が最も高い月を保持
print("各顧客の消費額が最も高い月:")
result = df.sort_values("消費額", ascending=False).drop_duplicates(
subset=["顧客"],
keep="first"
).sort_values("顧客")
print(result)
print()
# 各顧客の最初のレコードを保持(月順)
print("各顧客の最初のレコード:")
result = df.sort_values("月").drop_duplicates(
subset=["顧客"],
keep="first"
)
print(result)
削除せずに重複をマーク
例
import pandas as pd
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"都市": ["北京", "上海", "北京", "広州", "深セン"]
})
# 重複マーク用の列を追加
df["重複フラグ"] = df.duplicated(subset=["名前"], keep=False)
print("重複行のマーク:")
print(df)
print()
# または groupby を使用してマークする
df["重複回数"] = df.groupby("名前")["名前"].transform("count")
df["初回フラグ"] = ~df.duplicated(subset=["名前"], keep="first")
print("グループごとの重複回数の集計:")
print(df)
df = pd.DataFrame({
"名前": ["田中", "佐藤", "田中", "鈴木", "佐藤"],
"都市": ["北京", "上海", "北京", "広州", "深セン"]
})
# 重複マーク用の列を追加
df["重複フラグ"] = df.duplicated(subset=["名前"], keep=False)
print("重複行のマーク:")
print(df)
print()
# または groupby を使用してマークする
df["重複回数"] = df.groupby("名前")["名前"].transform("count")
df["初回フラグ"] = ~df.duplicated(subset=["名前"], keep="first")
print("グループごとの重複回数の集計:")
print(df)
注意事項
1. 「完全な重複」と「部分的な重複」を区別する
完全な重複とはすべての列の値が同じことを指し、部分的な重複とは特定の列が同じことを指します。重複を判断する列は、subsetパラメータを使用して指定します。
2. 保持ポリシーの選択
業務要件に応じて、最初の行を保持するか、最後の行を保持するか、またはどれも保持しないかを選択します。どの行を保持するかは、その後の分析結果に影響を与える可能性があります。
3. データ型の影響
重複を判断する際にはデータ型も考慮されます。例えば、整数の 1 と浮動小数点数の 1.0 は異なるものと見なされます。
その他の関連コンテンツ重複データを削除する前に、重複の原因と分布を分析し、削除操作によって重要な情報が失われないことを確認することをお勧めします。