最初のCSVのヘッダーを基準にし、後続ファイルの列名・列順が完全に一致するか確認してからデータ行だけを追加します。横方向の結合ではありません。
この記事の内容
対象・検証範囲:CPython 3.12.14 / Linux。掲載サンプルと期待する出力を照合。標準ライブラリのみ。
どんな結合に使えるか
同じ形式で出力されたファイルを、上から順に積み重ねる縦結合の例です。IDを照合して別の列を付け足す結合には使いません。
前提は、すべてのCSVに1行のヘッダーがあり、列名・列順が同じこと。データは文字列として保持し、同じ行が複数ファイルにあっても勝手に削除しません。空のファイルやヘッダーの違いが見つかったら、出力を作る前に止めます。
2つの入力を結合するコード
次の例は、文字列として読み込んだCSVのリストを受け取ります。空行は読み飛ばしますが、列数の違うレコードはエラーにします。
import csv
import io
def merge_csv(texts):
if not texts:
raise ValueError("入力がありません")
header = None
data = []
for file_no, text in enumerate(texts, start=1):
rows = csv.reader(io.StringIO(text, newline=""), strict=True)
current = next(rows, None)
if not current or len(set(current)) != len(current):
raise ValueError(f"入力{file_no}: 空または重複ヘッダー")
if any(not name.strip() for name in current):
raise ValueError(f"入力{file_no}: 空の列名")
if header is None:
header = current
elif current != header:
raise ValueError(f"入力{file_no}: ヘッダー不一致")
for record in rows:
if not record:
continue
if len(record) != len(header):
raise ValueError(f"入力{file_no}: 列数不一致")
data.append(record)
output = io.StringIO(newline="")
writer = csv.writer(output, lineterminator="\n")
writer.writerow(header)
writer.writerows(data)
return output.getvalue()
result = merge_csv(["id,name\n001,ノート\n", "id,name\n002,ペン\n"])
print(result, end="")
try:
merge_csv(["id,name\n001,ノート\n", "name,id\nペン,002\n"])
except ValueError as error:
print(error)
期待する結果とファイルでの使い方
id,name
001,ノート
002,ペン
入力2: ヘッダー不一致
ヘッダーは1回だけ出力され、IDの先頭ゼロも残ります。2回目の呼び出しは列順を入れ替えた入力で、意図どおり止まることを確認しています。
実ファイルではpathlib.Pathのread_text(encoding="utf-8-sig")などで各ファイルを読み、文字列のリストをmerge_csv()へ渡します。返った文字列は新しいファイルをopen("merged.csv", "x", encoding="utf-8", newline="")で開き、write()で保存します。
入力順が必要なら、ファイル名の並びが期待どおりかを明示的に確認してください。1.csv, 10.csv, 2.csvの文字列順は、数値の順とは違います。出力ファイルを入力フォルダーへ置くと、次回の一括読み込みに混ざるので、入力と出力を分けます。
件数で結合を確かめる
結果のデータ件数は、各入力のデータ件数を合計したものと一致させます。ただし、ヘッダーと読み飛ばした空行を数えないこと。セル内改行があるCSVでは、物理的な行数で数えると合いません。
同じIDが重なる場合、それは結合の失敗とは限りません。「残す・削除する・内容を比べて止める」のどれが必要かは業務上のルールです。重複処理の例を使う前に、何を同一とみなすか決めてください。
制限とエラーの意味
この実装は全データをメモリーに保持します。巨大ファイル向けのストリーミング処理ではありません。列名の前後の空白も区別するので、idとid は不一致です。違いを無視して結合する前に、出力元の仕様を確かめます。
途中のデータ行にヘッダーと同じ文字列が混入していても、自動では削除しません。本物の値との区別がつかないためです。構造確認にはCSVの検査を併用します。
参考にした公式資料
- Python公式: csv — CSVファイルの読み書き確認日:2026.09.20
- Python公式: pathlib — ファイルパス確認日:2026.09.20
掲載サンプルは記載のPython環境で実行確認しています。すべてのOS・入力データを保証するものではありません。 編集・検証方針