Pythonで重複チェックを自動化する方法|データ・ファイル別コピペコードと定期実行の設定手順

「名簿に同じ社員番号が2件入っていた」「経費申請が二重登録されていた」「同じファイルが複数フォルダに存在して、どれが最新版かわからない」

こういう重複の問題は、手動でチェックしていると必ず見落としが起きます。私も一度、採用候補者の名簿にメールアドレスの重複があることに気づかず、同じ人に2通送ってしまったことがあります。

この記事では、Pythonで重複チェックを自動化するコードを「データ重複」と「ファイル重複」の2種類に分けてコピペ即使用レベルで解説します。毎朝自動実行してメール通知まで飛ばすフルフローも含めています。

結論:どちらの重複チェックが必要か

種類 課題 使うコード
データ重複 CSVや名簿に同じ行・値が入っている pandas duplicated()
ファイル重複 同じ内容のファイルが複数フォルダにある ハッシュ比較(hashlib)

どちらも「毎朝自動実行+重複があればメール通知」というフローで自動化できます。

【データ編】CSVの重複チェック基本コード

全列が一致する完全重複を検出・削除

import pandas as pd

# CSVを読み込む
df = pd.read_csv("名簿.csv", encoding="utf-8-sig")

# 完全重複行を検出
duplicates = df[df.duplicated(keep=False)]

if len(duplicates) > 0:
    print(f"重複行が {len(duplicates)} 件見つかりました:")
    print(duplicates)

    # 重複を削除(最初の1件を残す)
    df_clean = df.drop_duplicates(keep="first")
    df_clean.to_csv("名簿_重複削除後.csv", index=False, encoding="utf-8-sig")
    print("重複削除後のファイルを保存しました。")
else:
    print("重複はありません。")

特定の列だけで重複チェック

import pandas as pd

df = pd.read_csv("名簿.csv", encoding="utf-8-sig")

# メールアドレス列だけで重複チェック
duplicate_emails = df[df.duplicated(subset=["メールアドレス"], keep=False)]

if len(duplicate_emails) > 0:
    print(f"メールアドレスの重複が {len(duplicate_emails)} 件:")
    print(duplicate_emails[["氏名", "メールアドレス"]])
else:
    print("メールアドレスの重複なし")

【業務シーン別】コピペで使えるコード5選

シーン1:名簿のメールアドレス重複チェック

採用候補者・取引先リストでの二重登録検出。

import pandas as pd

def check_email_duplicates(csv_path: str) -> None:
    df = pd.read_csv(csv_path, encoding="utf-8-sig")

    dupes = df[df.duplicated(subset=["メールアドレス"], keep=False)]

    if dupes.empty:
        print("✅ 重複なし")
        return

    print(f"⚠️ 重複メールアドレスが {len(dupes)} 件見つかりました:")
    for email, group in dupes.groupby("メールアドレス"):
        print(f"\n  {email}")
        for _, row in group.iterrows():
            print(f"    → {row['氏名']} (行{row.name + 2})")

check_email_duplicates("候補者名簿.csv")

シーン2:社員番号の重複チェック(人事データ)

import pandas as pd

df = pd.read_csv("社員マスタ.csv", encoding="utf-8-sig")

# 社員番号の重複を検出
dupes = df[df.duplicated(subset=["社員番号"], keep=False)]

if not dupes.empty:
    print("⚠️ 社員番号が重複しています:")
    print(dupes[["社員番号", "氏名", "部署"]].to_string())
else:
    print("✅ 社員番号の重複なし")

シーン3:経費申請の重複チェック(日付×金額×申請者)

同じ内容の経費が二重提出されていないか確認します。

import pandas as pd

df = pd.read_csv("経費申請.csv", encoding="utf-8-sig")

# 申請者・日付・金額の3列が一致する重複を検出
check_cols = ["申請者", "申請日", "金額"]
dupes = df[df.duplicated(subset=check_cols, keep=False)]

if not dupes.empty:
    print(f"⚠️ 経費申請の重複が {len(dupes)} 件:")
    print(dupes[check_cols + ["件名"]].to_string())

    # 重複行をExcelにエクスポート(確認用)
    dupes.to_excel("重複申請_要確認.xlsx", index=False)
    print("重複リストを重複申請_要確認.xlsxに保存しました。")

シーン4:注文番号の重複チェック

import pandas as pd

df = pd.read_csv("注文データ.csv", encoding="utf-8-sig")

dupes = df[df.duplicated(subset=["注文番号"], keep=False)]

if not dupes.empty:
    print(f"⚠️ 注文番号の重複: {dupes['注文番号'].unique().tolist()}")
    dupes.to_csv("重複注文_要確認.csv", index=False, encoding="utf-8-sig")
else:
    print("✅ 注文番号に重複なし")

シーン5:勤怠データの同一日時打刻重複

import pandas as pd

df = pd.read_csv("勤怠データ.csv", encoding="utf-8-sig")

# 社員IDと打刻日時が同一の重複を検出
dupes = df[df.duplicated(subset=["社員ID", "打刻日時"], keep=False)]

if not dupes.empty:
    print(f"⚠️ 打刻重複が {len(dupes)} 件:")
    print(dupes[["社員ID", "氏名", "打刻日時"]].to_string())

【ファイル編】重複ファイルの自動検出コード

ファイル名が違っても中身が同じファイルを検出します。ハッシュ値(MD5)を比較するため、確実に同一ファイルを特定できます。

import hashlib
import os
from collections import defaultdict
from pathlib import Path

def get_file_hash(filepath: str) -> str:
    """ファイルのMD5ハッシュを返す"""
    h = hashlib.md5()
    with open(filepath, "rb") as f:
        while chunk := f.read(8192):
            h.update(chunk)
    return h.hexdigest()

def find_duplicate_files(folder: str) -> None:
    """フォルダ内の重複ファイルを検出して表示"""
    hash_map = defaultdict(list)

    for path in Path(folder).rglob("*"):
        if path.is_file():
            file_hash = get_file_hash(str(path))
            hash_map[file_hash].append(str(path))

    duplicates = {k: v for k, v in hash_map.items() if len(v) > 1}

    if not duplicates:
        print("✅ 重複ファイルなし")
        return

    total = sum(len(v) - 1 for v in duplicates.values())
    print(f"⚠️ 重複ファイルが {len(duplicates)} グループ(合計 {total} 件の余分なコピー):")

    for i, (_, paths) in enumerate(duplicates.items(), 1):
        print(f"\n重複グループ {i}:")
        for p in paths:
            size = os.path.getsize(p)
            print(f"  {p}  ({size:,} bytes)")

find_duplicate_files(r"C:\業務\書類")

重複を見つけたらメール通知するフルフローコード

重複チェックの結果をGmailで自動通知します。

import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from datetime import date

# --- 設定 ---
CSV_PATH = "名簿.csv"
CHECK_COLUMN = "メールアドレス"
GMAIL_ADDRESS = "your@gmail.com"      # 送信元Gmailアドレス
GMAIL_APP_PASSWORD = "xxxx xxxx xxxx xxxx"  # Gmailアプリパスワード
NOTIFY_TO = "notify@example.com"      # 通知先メールアドレス

def send_notification(subject: str, body: str) -> None:
    msg = MIMEMultipart()
    msg["From"] = GMAIL_ADDRESS
    msg["To"] = NOTIFY_TO
    msg["Subject"] = subject
    msg.attach(MIMEText(body, "plain", "utf-8"))

    with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
        server.login(GMAIL_ADDRESS, GMAIL_APP_PASSWORD)
        server.send_message(msg)

def check_and_notify() -> None:
    df = pd.read_csv(CSV_PATH, encoding="utf-8-sig")
    dupes = df[df.duplicated(subset=[CHECK_COLUMN], keep=False)]
    today = date.today().strftime("%Y/%m/%d")

    if dupes.empty:
        print(f"[{today}] 重複なし")
        return

    # 重複があればメール通知
    body = f"【重複チェック結果】{today}\n\n"
    body += f"{CHECK_COLUMN}の重複が {len(dupes)} 件見つかりました。\n\n"
    body += dupes[[CHECK_COLUMN]].drop_duplicates().to_string()
    body += f"\n\nファイル: {CSV_PATH}"

    send_notification(
        subject=f"[要確認] 重複データ検出 {today}",
        body=body
    )
    print(f"[{today}] 重複 {len(dupes)} 件。メール通知を送信しました。")

check_and_notify()

Gmailアプリパスワードの取得方法:
Googleアカウント設定 → セキュリティ → 2段階認証を有効化 → アプリパスワードを生成

タスクスケジューラで毎朝自動実行する設定

Pythonスクリプトを毎朝定時に自動実行します。

手順

  1. 上記コードを check_duplicates.py として保存
  2. Windowsキー → 「タスクスケジューラ」を起動
  3. 「基本タスクの作成」→ タスク名を入力(例:重複チェック自動実行)
  4. トリガー:「毎日」→ 時刻を設定(例:9:00)
  5. 操作:「プログラムの開始」
    • プログラム:python
    • 引数:C:\Users\user\scripts\check_duplicates.py
  6. 完了 → 手動実行でテスト

実行ログを記録する場合:

import logging
logging.basicConfig(
    filename="duplicate_check.log",
    level=logging.INFO,
    format="%(asctime)s %(message)s"
)
logging.info("重複チェック完了")

Google Colabですぐ試す手順

Pythonのインストールなしに、ブラウザだけで動かせます。

  1. colab.research.google.com にアクセス
  2. 「新しいノートブック」を作成
  3. CSVファイルをColabにアップロード:
from google.colab import files
uploaded = files.upload()  # ファイル選択ダイアログが開く
  1. pandas をインポートしてコードを貼り付けて実行

よくある失敗と対処法

失敗1:duplicated() が期待通りに動かない

全角・半角・スペースの違いで「同じ値」として認識されないケースがあります。

# 前処理:スペース除去・小文字統一
df["メールアドレス"] = df["メールアドレス"].str.strip().str.lower()
dupes = df[df.duplicated(subset=["メールアドレス"], keep=False)]

失敗2:日本語CSVが文字化けする

# encodingを変えて試す
df = pd.read_csv("名簿.csv", encoding="utf-8-sig")   # BOM付きUTF-8
df = pd.read_csv("名簿.csv", encoding="shift_jis")    # ShiftJIS(古いExcel)

失敗3:ファイル重複チェックで大きなファイルが遅い

MD5ハッシュの計算はファイルサイズに比例します。最初にファイルサイズで絞り込むことで高速化できます。

# サイズが同じファイルだけをハッシュ比較する(高速化)
from collections import defaultdict
size_map = defaultdict(list)
for path in Path(folder).rglob("*"):
    if path.is_file():
        size_map[path.stat().st_size].append(path)

# サイズが重複するファイルのみハッシュを計算
for size, paths in size_map.items():
    if len(paths) > 1:
        # ここでハッシュ比較を行う
        pass

失敗4:スケジュール実行がサイレントに失敗している

タスクスケジューラのログを確認し、エラーが出ていないかを週次で確認してください。Pythonの実行ログをファイルに書き出しておくと原因調査が楽になります。

よくある質問(FAQ)

Q:pandas がインストールされていない場合はどうすればいいですか?
A:コマンドプロンプトで pip install pandas を実行してください。Google ColabはPython環境が整っているため、インストール不要です。

Q:Excelファイル(.xlsx)も重複チェックできますか?
A:できます。pd.read_csv()pd.read_excel() に変えるだけです。

df = pd.read_excel("名簿.xlsx", sheet_name="Sheet1")

Q:重複行を自動削除していいですか?
A:自動削除は慎重にしてください。「どちらの行が正しいか」は人間が判断する必要があります。自動化では「重複を検出してレポートする」までにとどめ、削除は確認後に手動で行うか、承認フローを組み込んだフルフローを設計することをおすすめします。

Q:ChatGPTでこのコードを修正してもらえますか?
A:できます。「このPythonコードで○○列ではなく○○列と○○列の組み合わせで重複チェックしたい」というように、具体的な変更内容を伝えれば修正してもらえます。コードを丸ごとプロンプトに貼り付けて指示するのが最速です。

まとめ

  • CSVのデータ重複は pandas.duplicated() で列単位・複数列組み合わせで検出できる
  • ファイル重複はMD5ハッシュ比較で中身が同じファイルを検出できる
  • 「チェック→通知」のフルフローをタスクスケジューラで毎朝自動実行することで手動作業をゼロにできる
  • 前処理(空白除去・小文字統一)をしないと見落としが起きる
  • 自動削除は危険。検出と通知まで自動化し、削除は確認後に行う

このコードはCSVのデータクレンジング記事で解説しているクレンジングプロセスの一部として使えます。重複チェックはクレンジングの最初のステップです。

Pythonの環境構築がまだの方は、Google Colabから始めてください。インストール不要でブラウザだけで動かせます。

業務全体のデータ整理ワークフローを組みたい方は、こちらのハブ記事もあわせて参考にしてください。
データ整理を効率化するツールと仕組み化の手順

コメント