業務では Excel ファイルでデータをやり取りする機会が多いです。pandas は Excel ファイルの読み書きに対応していますが、内部で使うライブラリによって機能や挙動が異なります。ここでは openpyxl を使った Excel 連携を解説します。
必要なライブラリ
pandas 単体では Excel を扱えません。読み書きには追加のライブラリが必要です。
# インストール # pip install openpyxl import pandas as pd # openpyxl がインストールされていれば自動的に使われる df = pd.read_excel('data.xlsx')
Excel 関連のライブラリは複数あり、用途によって使い分けます。
| ライブラリ | 対応形式 | 用途 |
|---|---|---|
| openpyxl | .xlsx | 読み書き両対応、書式設定可 |
| xlrd | .xls | 古い形式の読み込み専用 |
| xlsxwriter | .xlsx | 書き込み専用、高機能 |
現在は openpyxl が最も汎用的で、pandas のデフォルトエンジンにもなっています。
基本的な読み込み
import pandas as pd # 基本の読み込み df = pd.read_excel('data.xlsx') # シートを指定 df = pd.read_excel('data.xlsx', sheet_name='Sheet1') # シート番号で指定(0始まり) df = pd.read_excel('data.xlsx', sheet_name=0)
複数シートを一度に読み込むこともできます。
# 全シートを辞書で取得 all_sheets = pd.read_excel('data.xlsx', sheet_name=None) print(all_sheets.keys()) # dict_keys(['Sheet1', 'Sheet2', 'Sheet3']) # 特定の複数シートを読み込み sheets = pd.read_excel('data.xlsx', sheet_name=['Sheet1', 'Sheet3'])
読み込みオプション
実務の Excel ファイルは、1 行目がヘッダーでないことも多いです。さまざまなオプションで対応できます。
# ヘッダー行を指定(0始まり) df = pd.read_excel('data.xlsx', header=2) # 3行目がヘッダー # ヘッダーなし df = pd.read_excel('data.xlsx', header=None) # 読み込む行をスキップ df = pd.read_excel('data.xlsx', skiprows=5) # 最初の5行をスキップ # 特定の行をスキップ(リストで指定) df = pd.read_excel('data.xlsx', skiprows=[0, 2, 4]) # 読み込む行数を制限 df = pd.read_excel('data.xlsx', nrows=100)
列の指定も柔軟にできます。
# 特定の列のみ読み込み df = pd.read_excel('data.xlsx', usecols='A:C') # A〜C列 df = pd.read_excel('data.xlsx', usecols='A,C,E') # A, C, E列 df = pd.read_excel('data.xlsx', usecols=[0, 2, 4]) # インデックス指定 # 列名で指定 df = pd.read_excel('data.xlsx', usecols=['名前', '金額'])
データ型の指定
Excel から読み込むと、意図しない型変換が起きることがあります。dtype パラメータで明示的に指定できます。
# 型を指定して読み込み df = pd.read_excel('data.xlsx', dtype={ '社員番号': str, # 先頭ゼロを保持 '金額': float, 'フラグ': bool })
日付列は自動認識されますが、うまくいかない場合は parse_dates を使います。
# 日付列を指定 df = pd.read_excel('data.xlsx', parse_dates=['登録日', '更新日']) # 複数列を結合して日付に df = pd.read_excel('data.xlsx', parse_dates={'日時': ['日付', '時刻']})
便利だが、文字列の数字が数値になったり、先頭ゼロが消えたりする
意図した型で読み込める。特に ID やコードは str 指定が安全
基本的な書き込み
import pandas as pd df = pd.DataFrame({ '名前': ['田中', '佐藤', '鈴木'], '点数': [85, 92, 78] }) # 基本の書き込み df.to_excel('output.xlsx', index=False) # シート名を指定 df.to_excel('output.xlsx', sheet_name='成績表', index=False)
index=False を指定しないと、DataFrame のインデックスが A 列に出力されます。多くの場合は不要なので False にします。
複数シートへの書き込み
複数の DataFrame を別々のシートに書き込むには ExcelWriter を使います。
import pandas as pd df1 = pd.DataFrame({'A': [1, 2, 3]}) df2 = pd.DataFrame({'B': [4, 5, 6]}) with pd.ExcelWriter('output.xlsx', engine='openpyxl') as writer: df1.to_excel(writer, sheet_name='データ1', index=False) df2.to_excel(writer, sheet_name='データ2', index=False)
既存ファイルにシートを追加する場合は mode='a' を指定します。
# 既存ファイルにシートを追加 with pd.ExcelWriter('output.xlsx', engine='openpyxl', mode='a') as writer: df3.to_excel(writer, sheet_name='データ3', index=False)
書式設定との連携
pandas の to_excel は書式設定に限界があります。細かい書式が必要な場合は、openpyxl を直接使います。
import pandas as pd from openpyxl import load_workbook from openpyxl.styles import Font, Alignment, PatternFill # まず pandas で基本データを書き込み df = pd.DataFrame({ '商品': ['りんご', 'みかん', 'バナナ'], '価格': [150, 100, 200] }) df.to_excel('output.xlsx', index=False) # openpyxl で書式を追加 wb = load_workbook('output.xlsx') ws = wb.active # ヘッダーに書式を設定 for cell in ws[1]: cell.font = Font(bold=True, color='FFFFFF') cell.fill = PatternFill('solid', fgColor='4472C4') cell.alignment = Alignment(horizontal='center') # 列幅を調整 ws.column_dimensions['A'].width = 15 ws.column_dimensions['B'].width = 10 wb.save('output.xlsx')
テンプレートへの書き込み
業務では、書式設定済みのテンプレートにデータを流し込むことが多いです。
from openpyxl import load_workbook import pandas as pd # テンプレートを開く wb = load_workbook('template.xlsx') ws = wb.active # DataFrame を準備 df = pd.DataFrame({ '名前': ['田中', '佐藤'], '金額': [10000, 20000] }) # 特定のセルからデータを書き込み start_row = 5 # 5行目から for i, row in df.iterrows(): ws.cell(row=start_row + i, column=2, value=row['名前']) ws.cell(row=start_row + i, column=3, value=row['金額']) wb.save('output.xlsx')
シンプルなデータ出力に最適。書式は最低限のみ。
細かい書式設定、テンプレート活用、セル結合などが必要な場合に使う。
パフォーマンスの注意点
Excel ファイルの読み書きは CSV に比べて遅いです。大量データを扱う場合は注意が必要です。
import pandas as pd import time # 大きなデータ df = pd.DataFrame({'A': range(100000), 'B': range(100000)}) # Excel書き込み start = time.time() df.to_excel('large.xlsx', index=False) print(f"Excel: {time.time() - start:.2f}秒") # CSV書き込み start = time.time() df.to_csv('large.csv', index=False) print(f"CSV: {time.time() - start:.2f}秒") # Excel: 5.23秒 # CSV: 0.15秒
大量データは CSV で処理し、最終的な出力のみ Excel にするのが効率的です。