Pythonで大量のCSVファイルを結合する方法

プログラミング

Pythonで大量のCSVファイルを結合する方法

Pythonは、その柔軟性と豊富なライブラリにより、大量のCSVファイルを効率的に結合するための強力なツールとなります。特に、pandasライブラリは、データ操作と分析を容易にし、このタスクに最適です。ここでは、その具体的な方法と、関連する考慮事項について詳しく説明します。

1. pandasライブラリを使用した基本的な結合方法

pandasは、DataFrameというデータ構造を提供しており、CSVファイルの読み込み、操作、結合を直感的に行うことができます。

1.1. CSVファイルのリスト化

まず、結合したいCSVファイルが保存されているディレクトリから、それらのファイルパスをリストとして取得する必要があります。Pythonの標準ライブラリであるosまたはglobモジュールがこれに役立ちます。

osモジュールを使用する場合:

import os

directory_path = '/path/to/your/csv/files'
csv_files = [os.path.join(directory_path, f) for f in os.listdir(directory_path) if f.endswith('.csv')]

globモジュールを使用する場合(より簡潔です):

import glob

directory_path = '/path/to/your/csv/files'
csv_files = glob.glob(os.path.join(directory_path, '*.csv'))

1.2. 各CSVファイルの読み込みと結合

取得したファイルリストをループ処理し、各CSVファイルをpandas DataFrameとして読み込みます。そして、それらを一つのDataFrameに結合していきます。

import pandas as pd

all_data = pd.DataFrame()

for f in csv_files:
    df = pd.read_csv(f)
    all_data = pd.concat([all_data, df], ignore_index=True)

ここで、pd.concat()関数が重要な役割を果たします。

  • 第一引数には、結合したいDataFrameのリストを指定します。
  • ignore_index=Trueを指定することで、元のDataFrameのインデックスを無視し、新しく連続したインデックスを生成します。これにより、結合後のDataFrameでインデックスの重複を防ぎます。

1.3. 結合結果の保存

結合されたDataFrameは、新しいCSVファイルとして保存することができます。

output_file = 'combined_data.csv'
all_data.to_csv(output_file, index=False)

index=Falseを指定することで、DataFrameのインデックスをCSVファイルに書き出すことを防ぎます。

2. 大量ファイルを扱う上での注意点と最適化

ファイル数や各ファイルのサイズが非常に大きい場合、メモリ使用量や処理速度に影響が出ます。以下に、これらの課題に対処するための方法を説明します。

2.1. メモリ使用量の管理

  • チャンク読み込み: pandasのread_csv()関数は、chunksize引数を使用してファイルを分割して読み込むことができます。これにより、一度にメモリにロードされるデータ量を減らすことができます。
chunk_size = 10000  # 例: 1万行ごとに処理
all_data_chunks = []

for f in csv_files:
    for chunk in pd.read_csv(f, chunksize=chunk_size):
        all_data_chunks.append(chunk)

all_data = pd.concat(all_data_chunks, ignore_index=True)
  • データ型の最適化: CSVファイルを読み込む際に、必要のないデータ型(例: 全て数字の列をobject型で読み込む)を適切に指定することで、メモリ使用量を削減できます。dtype引数を使用します。
  • 不要な列の除外: 結合の必要がない列は、読み込み時に除外することでメモリ使用量を削減できます。usecols引数を使用します。

2.2. 処理速度の向上

  • 並列処理: multiprocessingライブラリやjoblibライブラリなどを利用して、複数のCPUコアでファイルを並列に処理することで、処理時間を大幅に短縮できます。
  • ファイル名の正規化: ファイル名に一貫性がない場合、結合対象のファイルを正しく取得できない可能性があります。結合前にファイル名を整理することを検討してください。

3. 結合時の共通の考慮事項

CSVファイルを結合する際には、いくつかの共通の考慮事項があります。

3.1. ヘッダー行の扱い

  • ヘッダーあり・なし: 結合するCSVファイルが全て同じヘッダー行を持っている場合、最初のファイルでヘッダーを読み込み、それ以降のファイルではヘッダーなしで読み込むという処理が一般的です。
header_present = True # 最初のファイルにヘッダーがある場合
all_data = pd.DataFrame()

for i, f in enumerate(csv_files):
    if i == 0:
        df = pd.read_csv(f)
    else:
        df = pd.read_csv(f, header=None) # ヘッダーなしで読み込む
    all_data = pd.concat([all_data, df], ignore_index=True)

# 必要に応じて、結合後にヘッダーを再設定
if header_present:
    all_data.columns = ['col1', 'col2', ...] # 元のヘッダー名に合わせて設定

3.2. 列の不一致

  • 列名の違い: 結合するCSVファイル間で列名が異なる場合、pd.concat()はデフォルトでは列を結合せずに、存在しない列はNaN(Not a Number)で埋めます。
  • 列の順序の違い: 列の順序が異なっても、列名が一致していれば正しく結合されます。
  • 列の追加/削除: 特定の列を追加したり削除したりして、全てのCSVファイルで列構成を統一してから結合することも有効な手段です。

3.3. 文字エンコーディング

  • CSVファイルが異なる文字エンコーディング(例: UTF-8, Shift_JIS)で保存されている場合、読み込み時にエラーが発生する可能性があります。read_csv()関数のencoding引数で適切なエンコーディングを指定する必要があります。
df = pd.read_csv(f, encoding='shift_jis') # 例: Shift_JISの場合

4. まとめ

Pythonとpandasライブラリを活用することで、大量のCSVファイルの結合は非常に効率的に行うことができます。ファイル数やサイズに応じて、チャンク読み込みやデータ型最適化などのメモリ管理、並列処理による速度向上のテクニックを適用することが重要です。また、結合するCSVファイル間のヘッダー、列構成、文字エンコーディングの差異に注意することで、より確実で正確な結合処理を実現できます。これらの方法を理解し、状況に応じて適切に使い分けることで、データ処理の生産性を大きく向上させることができるでしょう。