[小ネタ]PandasでExcelファイルを扱う(OpenPyXL)

2019.10.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

データアナリティクス事業本部のkobayashiです。長野はすっかり寒くなってきました。

PandasでExcelファイルからpandas.DataFrameとしてデータを読み込み加工する必要がありました。従来であればpandas.read_excel()関数を使っていましたがread_excel()内部で利用しているxlrdというライブラリのサイトで以下の記述がありました。

GitHub - python-excel/xlrd

This library currently has no active maintainers. You are advised to use OpenPyXL instead. If you absolutely have to read .xls files, then xlrd will probably still work for you, but please do not submit issues complaining that this library will not read your corrupted or non-standard file. Just because Excel or some other piece of software opens your file does not mean it is a valid xls file.

そこで更新が止まっているライブラリを使うのを止め上記で言及されているOpenPyXLを使ったのでその内容を簡単にまとめます。

環境

  • Python 3.7.4
    • Pandas 0.25.1
    • OpenPyXL 3.0.0

OpenPyXL

OpenPyXLはPythonでExcelファイルを読み書きするためのライブラリで、PHPExcelがベースになっているようです。PHPExcelはPHPでかつてPHPを扱っていた際にもお世話になったライブラリなので何処か親近感が湧きます。 OpenPyXLですとPandasを使わなくてもExcelファイルを扱えるのでpandas.read_excel()関数よりも汎用性があります。

OpenPyXL 公式

openpyxl is a Python library to read/write Excel 2010 xlsx/xlsm/xltx/xltm files. It was born from lack of existing library to read/write natively from Python the Office Open XML format. All kudos to the PHPExcel team as openpyxl was initially based on PHPExcel.

インストール

pipで簡単にインストールできます。

pip install openpyxl

またExcel内の画像ファイルを扱う場合はpillowライブラリが必要なのでインストールしておきます。

pip install pillow

Excelファイルの読み込み

以下の形でワークシートを読み込みます。

from openpyxl import load_workbook

wb = load_workbook(filename = 'sample.xlsx')
sheet = wb['sheet1']

load_workbookではいくつか有用なオプションが使えるので紹介します。

  • read_only (bool default:False)
    • 読み込み専用に最適化されるのでメモリ使用量が少なく読み込み時間も短い
  • keep_vba (bool default:False)
    • VBAを保持したままの状態で開く
  • data_only (bool default:False)
    • 数式を含むセルの振る舞い
    • 「数式」もしくは「最後にExcelに保存したときの値」を返す
  • keep_links (bool default:True)
    • 外部ワークブックへのリンクを返す

特にread_onlyオプションはExcelファイルのデータを読み込むだけでExcelファイルをOpenPyXLで編集しないなら使用したほうが良いです。読み込み時間が半分以下になります。

読み込むワークシートを指定するときはシート名を指定しなくてはいけませんがsheetnamesプロパティはシート名のリストなので以下の様にすればシート名ではなく番号で読み込めます。

# 先頭のシートを読み込む
sheet = wb[wb.sheetnames[0]]

DataFrameへの変換

DataFrameのコンストラクタを利用してvaluesプロパティを変換します。

import pandas as pd

sheet = wb["sheet1"]
data = sheet.values
df = pd.DataFrame(data)

ワークシートにヘッダー行がある場合は以下のようにします。

data = list(data)
df = pd.DataFrame(data[1:], columns=data[0])

ひとまずここまでできれば後はDataFrameの操作なので如何様にもなります。

まとめ

Excelに保存されているデータを扱う際にライブラリOpenPyXLを使ってDaraFrameに変換紹介しました。 Pandasのread_excel関数でも読み込めますがメンテナンスが終了している事と汎用性が高いことからOpenPyXLを使った方が良いと思います。

最後まで読んで頂いてありがとうございました。