mcpField
C
csv-excel-merger

csv-excel-merger

github.com/onewave-aiデータ・データベース3931.2k 回インストール1 週間前に更新
リポジトリ

csv-excel-merger について

csv-excel-mergerは、複数ファイルのデータを統合する人向けの、CSVとExcelの表を結合するスキルです。追加とキーによる結合の選択、列名やキーの正規化、競合処理、結果検証を扱い、行の欠落や重複、破損を防ぎます。

主な機能

  1. 01文字コード、区切り、行数、ヘッダーの確認
  2. 02追加とキー結合の選択
  3. 03列の対応付けとキーの正規化
  4. 04結合の検証と競合処理
  5. 05行数の確認と出力レポート

活用シーン

  1. 01異なる月のエクスポートデータの統合
  2. 02連絡先データと取引情報の結合
  3. 03複数ソースのリスト整理と重複排除

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/onewave-ai/claude-skills --skill csv-excel-merger

インストール後、Claude Code で/csv-excel-mergerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
merge_strategies.md
output_template.md
scripts/
profile_inputs.py

詳細

CSV/Excel マージ

表形式ファイルを結合し、行を気づかないうちに失ったり、重複させたり、破損させたりすることなく、整理された出力を作成します。

ワークフロー

このチェックリストをコピーして、進捗を記録してください。

- [ ] 1. Profile inputs
- [ ] 2. Choose append vs join
- [ ] 3. Map columns and normalize keys
- [ ] 4. Merge and resolve conflicts
- [ ] 5. Verify row math
- [ ] 6. Write output and report
  1. 入力をプロファイリングします。 まず、同梱のプロファイラーを実行してください。変更を加えることなく、エンコーディング、区切り文字、行数、ヘッダー、候補キー、ヘッダーの重複を報告します。

    python scripts/profile_inputs.py file1.csv file2.xlsx
    

    Excel ファイルはシートごとにプロファイリングされます。ブックに複数のシートがある場合は、どのシートを対象にするかユーザーに確認してください。

  2. 操作を選択します。 最も間違いやすい判断です。

    • 追加(積み重ね) - 異なるソースや期間の、同じ種類のレコード(1月と2月のエクスポート、3つのリードリストなど)に使います。pd.concatを使い、その後重複を削除します。
    • 結合(情報の補完) - 同じエンティティについて異なる情報(連絡先とその取引額など)に使います。キーを指定してpd.mergeを使います。
    • 迷った場合、ファイルの大半の列が共通なら追加します。ID 列だけが共通なら結合します。
  3. 列を対応付け、キーを正規化します。 ファイルごとに明示的な{original: unified}リネームマップを作成してください(よくあるバリエーションについてはreferences/merge_strategies.mdを参照)。対応関係が曖昧な場合は、ユーザーに提示してください。重複削除や結合の前にキー列を正規化します。空白を除去し、メールアドレスは小文字にし、電話番号から数字以外を除去し、日付形式を統一します。これを行わないと、[email protected] と[email protected]が別々の人として残ります。

  4. マージします。 ID、郵便番号、電話番号の先頭のゼロを保持できるよう、すべてのファイルをdtype=strで読み込み、その後、特定の列を変換します。

    import pandas as pd
    
    frames = []
    for path, rename in [("jan.csv", {"E-mail": "email"}), ("feb.xlsx", {"Email Address": "email"})]:
        df = (pd.read_excel(path, dtype=str) if path.endswith((".xlsx", ".xls"))
              else pd.read_csv(path, dtype=str, encoding="utf-8-sig",  # use the profiler's encoding
                            keep_default_na=False))
        df = df.rename(columns=rename)
        df["email"] = df["email"].str.strip().str.lower()
        df["source_file"] = path          # lineage for every row
        frames.append(df)
    
    combined = pd.concat(frames, ignore_index=True, sort=False)
    # Blank keys are not duplicates of each other: set them aside before deduping.
    has_key = combined["email"].fillna("") != ""
    # Later files win: list the most recent source last, then keep="last".
    deduped = combined[has_key].drop_duplicates(subset=["email"], keep="last")
    no_key = combined[~has_key]
    merged = pd.concat([deduped, no_key], ignore_index=True)
    

    結合する場合は、想定する関係を pandas に強制し、キーの重複で行数が増えるのではなく、エラーになるようにします。

    out = pd.merge(contacts, deals, on="email", how="left",
                   validate="one_to_one", indicator=True)
    unmatched = out[out["_merge"] == "left_only"]
    

    競合の処理方法(先頭/末尾/最も完全な行を保持、フィールドを結合、レビュー用にフラグ付け)については、references/merge_strategies.mdを参照してください。

  5. 報告前に検証します。 確認せずにマージ結果を渡してはいけません。

    rows_in = sum(len(f) for f in frames)
    assert len(merged) > 0, "merge produced an empty frame"
    assert len(merged) <= rows_in, "more rows out than in: check the join keys"
    assert deduped["email"].is_unique, "duplicate keys remain after dedupe"
    print(f"in={rows_in} out={len(merged)} removed={rows_in - len(merged)} blank_keys={len(no_key)}")
    print(merged["source_file"].value_counts())
    

    削除した重複行のうち3件を、ソースファイルと手作業で照合してください。アサーションで検証できるのは計算の正しさであり、正しい行が残ったかどうかではありません。

  6. 出力を書き込み、報告します。 references/output_template.mdのレイアウトを使用してください。

    • Excel ユーザー向けの CSV:to_csv(path, index=False, encoding="utf-8-sig")(BOM によって、Excel でアクセント記号が正しく読み込まれます)。
    • Excel:openpyxl をインストールしたうえで、to_excel(path, index=False)を使います。1つのシートに格納できるのは最大1,048,576行です。それを超える場合は分割するか、CSV/Parquet を使用してください。
    • これらのデータが空でない場合は、conflicts_review.csvまたはunmatched.csvも書き出してください。

pandas のバージョンに関する注意

現在の pandas は3.x(Python 3.11以降)です。マージに影響する違いは次のとおりです。

  • テキスト列のデフォルトの型はobjectではなくstrです。dtype == objectではなく、pd.api.types.is_string_dtype(col)で確認してください。
  • Copy-on-Write は常に有効です。df[col][mask] = xのような連鎖代入ではdfは更新されません(pandas は警告のみを出します)。df.loc[mask, col] = xを使ってください。
  • 解析された日時のデフォルトの解像度はマイクロ秒です。後続処理でナノ秒を想定している場合は、整数にキャストする前に.dt.as_unit("ns")を呼び出してください。
  • pd.read_excel(..., engine="calamine")(python-calamineが必要)を使うと、大きなブックを openpyxl よりはるかに速く読み込めます。

このスキルのコードは pandas 2.2 でも実行できます。

確認すべき失敗パターン

  • 結合による行数の増加 - 両方の側でキーが重複していると、行数が増加します。validate= で検出できます。
  • 先頭のゼロが失われる - dtype=str を指定せずに読み込むと、01234 が 1234 になります。
  • Excel によって変更された値 - 長い ID がすでに 1.23E+15 と表示されていたり、日付が元ファイルですでに再フォーマットされていたりする場合、pandas では復元できません。そうした値は報告してください。
  • ヘッダー行が1行目にない - タイトル部分を含むエクスポートには、skiprows= または header= が必要です。
  • エンコーディングの混在 - UTF-8 のファイルに cp1252 のファイルが1つ混在すると、é のような文字化けが発生します。プロファイラーはファイルごとのエンコーディングを報告します。
  • 列が気付かれずに削除される - 1つのファイルにしか存在しない列は、追加後にほとんど空になります。その列は保持して完全性を報告し、データを削除する場合は必ず明示してください。
  • 大きなファイル(数百 MB 超)- chunksize= を指定して読み込むか、Polars/DuckDB を使用し、すべてをメモリに読み込まず、キーのセットを使って重複を削除してください。

コメント