🥷

共通カラム名さえあれば、他が違っても複数のCSVを結合できる

に公開

📌はじめに

複数のCSVファイルを1つに結合したいとき、
IDなど共通のカラムは同じでも、ユーザーによって選択される情報が異なる場合、
対応するカラム名も変わることがあり、結合処理が複雑になりがちです。

本記事では、そういったケースをPythonでサクッと処理する方法を紹介します。


📌CSV の縦方向結合(列が異なるファイルの扱い)

実例と注意点

  • 複数のCSVをpandas.concatで縦に結合すると、列名が異なっていても 列名の和集合(union) として結合されます
  • 片方にしかない列は、結合後にNaN(欠損値)になります
  • 結合前にIDの重複をチェックし、重複があった場合は処理を中止することが推奨です。

例:Aファイル / Bファイル と結合結果


📌環境

python3.x


📌フォルダ構成

├── 1_flow/
│   └── file_join.py          # ファイルを結合するスクリプト
├── 2_data/                   # 結合したいファイルを入れる
│   ├── file_01.csv           
│   ├── file_02.csv           
│   └── ...                   
├── 3_output/
│   └── 結合.csv              # 結合結果
     

📌コード解説(file_join.py)

#=============================================
# 0.ライブラリ
#=============================================
import os
import glob
import pandas as pd
import sys
import subprocess


# CSVファイルのIDカラム名(必要に応じて変更してください)

ID = 'id'

#=============================================
# 1.パスの設定
#=============================================
parent_dpath = os.path.dirname(os.getcwd())


# Inputデータフォルダパス
INPUT_DNAME = "2_data"
input_dpath = os.path.join(parent_dpath, INPUT_DNAME)


# 出力先のフォルダパス
OUTPUT_DNAME = "3_output"
output_dpath = os.path.join(parent_dpath, OUTPUT_DNAME)
os.makedirs(output_dpath, exist_ok=True)


# 保存名
save_name = "結合.csv"
save_path = os.path.join(output_dpath, save_name)

#=============================================
# 2. 出力先フォルダの前回処理ファイルを削除
#=============================================
for f in os.listdir(output_dpath):
    file_path = os.path.join(output_dpath, f)
    if os.path.isfile(file_path):
        os.remove(file_path)

0. ライブラリと変数

  • os / glob:ファイルやフォルダの操作用
  • pandas:CSVの読み込み・結合・保存用
  • sys, subprocess:必要に応じて外部コマンド呼び出し用
  • ID:CSVファイル内の共通IDカラム名(必要に応じて変更)

1.パスの取得

  • os.path.dirname(os.getcwd()):現在の作業ディレクトリの親ディレクトリを取得
    → 入力フォルダや出力フォルダを親ディレクトリ基準で設定
  • INPUT_DNAME / OUTPUT_DNAME:入力・出力フォルダ名を定義
  • os.path.join(...):フルパスを作成
  • os.makedirs(..., exist_ok=True):出力フォルダが存在しない場合は自動作成

2. 出力フォルダの前回処理ファイルを削除

  • os.listdir(output_dpath) でフォルダ内のファイル一覧を取得
  • os.remove(file_path) で各ファイルを削除
    → 前回の結合ファイルや古いデータが残らないようにクリア

#=============================================
# 3.ファイルリスト取得
#=============================================
csv_files = glob.glob(os.path.join(input_dpath, "*.csv"))

if not csv_files:
    print("❌ CSVファイルが見つかりません。処理を終了します。")
    sys.exit(1)

#=============================================
# 4.CSV読み込み & 結合
#=============================================
data_list = []
for file in csv_files:
    try:
        df = pd.read_csv(file, encoding="utf-8")
    except UnicodeDecodeError:
        df = pd.read_csv(file, encoding="cp932")
    data_list.append(df)

data_df = pd.concat(data_list, axis=0, ignore_index=True)

#=============================================
# 5.重複IDチェック
#=============================================
if data_df[ID].duplicated().any():
    dup_ids = data_df.loc[data_df[ID].duplicated(), ID].unique()
    print(f"❌ 重複したIDが見つかりました: {list(dup_ids)}")
    print("処理を中止します。")
    sys.exit(1)

#=============================================
# 6.CSV保存
#=============================================
data_df.to_csv(save_path, encoding="cp932", index=False)

# 保存フォルダを開く
os.startfile(output_dpath)

3. ファイルリスト取得

  • glob.glob():入力フォルダ(2_data)内のCSVファイル名のリストを作成
  • CSVが1つも見つからなければ、処理を終了しエラーメッセージを表示
    → ユーザーに「ファイルが存在しない」ことを明示し、安全に処理を止める

4. CSV読み込み & 結合

  • 各CSVファイルを順番に読み込み、data_list に追加
    • encoding="utf-8" をまず試し、失敗した場合は encoding="cp932" で再読み込み
  • pd.concat(..., axis=0, ignore_index=True):縦方向に結合
    • 列が異なる場合も和集合として結合され、存在しない列は NaN になる

5. 重複IDチェック

  • data_df[ID].duplicated().any() で重複IDがあるか確認
  • 重複があった場合は該当IDを表示し、処理を中止
    → データの整合性を確保するための安全策

6. CSV保存

  • data_df.to_csv(save_path, encoding="cp932", index=False) で結合結果を保存
  • os.startfile(output_dpath):保存先フォルダを自動で開く(Windows環境)

--

📌まとめ

この方法を使えば、業務での大量データ処理や前処理が格段にスムーズになります。


参考リンクについて

GitHubリポジトリ
本記事で紹介したコードやサンプルデータはこちらで公開しています。

Discussion