csv-excel-merger について
csv-excel-mergerは、複数ファイルのデータを統合する人向けの、CSVとExcelの表を結合するスキルです。追加とキーによる結合の選択、列名やキーの正規化、競合処理、結果検証を扱い、行の欠落や重複、破損を防ぎます。
主な機能
- 01文字コード、区切り、行数、ヘッダーの確認
- 02追加とキー結合の選択
- 03列の対応付けとキーの正規化
- 04結合の検証と競合処理
- 05行数の確認と出力レポート
活用シーン
- 01異なる月のエクスポートデータの統合
- 02連絡先データと取引情報の結合
- 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.mdoutput_template.mdscripts/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
-
入力をプロファイリングします。 まず、同梱のプロファイラーを実行してください。変更を加えることなく、エンコーディング、区切り文字、行数、ヘッダー、候補キー、ヘッダーの重複を報告します。
python scripts/profile_inputs.py file1.csv file2.xlsxExcel ファイルはシートごとにプロファイリングされます。ブックに複数のシートがある場合は、どのシートを対象にするかユーザーに確認してください。
-
操作を選択します。 最も間違いやすい判断です。
- 追加(積み重ね) - 異なるソースや期間の、同じ種類のレコード(1月と2月のエクスポート、3つのリードリストなど)に使います。
pd.concatを使い、その後重複を削除します。 - 結合(情報の補完) - 同じエンティティについて異なる情報(連絡先とその取引額など)に使います。キーを指定して
pd.mergeを使います。 - 迷った場合、ファイルの大半の列が共通なら追加します。ID 列だけが共通なら結合します。
- 追加(積み重ね) - 異なるソースや期間の、同じ種類のレコード(1月と2月のエクスポート、3つのリードリストなど)に使います。
-
列を対応付け、キーを正規化します。 ファイルごとに明示的な
{original: unified}リネームマップを作成してください(よくあるバリエーションについてはreferences/merge_strategies.mdを参照)。対応関係が曖昧な場合は、ユーザーに提示してください。重複削除や結合の前にキー列を正規化します。空白を除去し、メールアドレスは小文字にし、電話番号から数字以外を除去し、日付形式を統一します。これを行わないと、[email protected]と[email protected]が別々の人として残ります。 -
マージします。 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を参照してください。
-
報告前に検証します。 確認せずにマージ結果を渡してはいけません。
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件を、ソースファイルと手作業で照合してください。アサーションで検証できるのは計算の正しさであり、正しい行が残ったかどうかではありません。
-
出力を書き込み、報告します。 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も書き出してください。
- Excel ユーザー向けの 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 を使用し、すべてをメモリに読み込まず、キーのセットを使って重複を削除してください。