HOWTO · Python
Python で Matlab mat ファイルを読む
このチュートリアルでは、Python で Matlab マットファイルを読み取って開く方法を示します。
このページの内容
MATLAB はワークスペースの変数を .mat ファイルに保存しますが、Python にはそれを開く標準的な方法はありません。MAT ファイルのバージョンに応じてリーダーライブラリを選ぶことになります。このガイドでは、ファイルの形式を見分け、scipy.io、h5py、mat4py、または matlab.engine API で変数を読み込む方法と、それぞれのアプローチが機能しなくなる限界を説明します。
MAT ファイルのバージョンに応じてリーダーを選ぶ
MATLAB にはこれまで 2 種類のファイルレイアウトがありました。MAT ファイルのバージョン 5 から 7.2 までは MATLAB 独自のバイナリ形式で、MATLAB で始まる 128 バイトのテキストヘッダーから始まります。さらに古い MATLAB 4 のファイルも同じクラシックレイアウトを使いますが、説明的なヘッダーを持たず、データ要素から直接始まります。scipy.io.loadmat は、ヘッダーの有無にかかわらずクラシック系のすべてを読み込めます。-v7.3 で保存されたファイルは HDF5 ファイルです。小さな MATLAB ユーザーブロックは残っていますが、データは HDF5 データセットとして格納されており、これを開くのが h5py です。NumPy 単体ではどちらのレイアウトも開けません。NumPy ができるのは、すでに読み込まれたデータセットを配列に変換することだけです。
何もインストールしなくても、ファイルの先頭バイトを見れば形式を判別できます。次の例を実行すると、よくある種類のファイルを一時フォルダーに 1 つずつ書き出し、ヘッダーで分類します。コード中の文字列と出力メッセージは英語のまま表示されます。
import os
import tempfile
folder = tempfile.mkdtemp()
classic = os.path.join(folder, "classic.mat")
modern = os.path.join(folder, "v73.mat")
with open(classic, "wb") as f:
f.write(b"MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Thu Oct 29 2026".ljust(128, b" "))
with open(modern, "wb") as f:
f.write(b"MATLAB 7.3 MAT-file, Platform: GLNXA64, HDF5 schema 1.00".ljust(512, b" "))
f.write(b"\x89HDF\r\n\x1a\n")
def mat_kind(path):
with open(path, "rb") as f:
head = f.read(128)
f.seek(512)
signature = f.read(8)
if b"HDF5" in head or signature.startswith(b"\x89HDF"):
return "MATLAB 7.3 (HDF5): read with h5py"
if head.startswith(b"MATLAB"):
return "MAT-file 7.2 or older: read with scipy.io.loadmat"
return "no v5+ header or HDF5 signature — possibly a MATLAB 4 file: try scipy.io.loadmat"
print(mat_kind(classic))
print(mat_kind(modern))
MAT-file 7.2 or older: read with scipy.io.loadmat
MATLAB 7.3 (HDF5): read with h5py
実際の 7.3 ファイルはヘッダーテキストに HDF5 と記され、ユーザーブロックの後ろに HDF5 シグネチャを持ちます。一方、バージョン 5〜7.2 のファイルのヘッダーは単に MATLAB で始まります。このチェックはその 2 つの目印だけで分類するため、どちらも現れない MATLAB 4 のファイルはフォールバックメッセージに振り分けられます。ただし scipy.io.loadmat はそれでも開けるので、その結果はファイルが読めない証拠ではなく、直接 loadmat を試す合図と考えてください。目安として、ファイルがバージョン 7.2 以前ならまず scipy.io.loadmat を使い、7.3 のファイルには h5py を使い、クラシックファイルから NumPy 配列ではなく素の Python リストが欲しいときは mat4py を選びます。matlab.engine は、MATLAB 本体がインストールされていて、複雑な型を完全な忠実度で扱う必要がある場合に限って使います。変数を Python に取り込んでしまえば、pandas で CSV や Excel に書き出せますし、あとで必要になれば scipy.io.savemat や HDF5 データセットで .mat ファイルを書き戻すこともできます。
以下のセクションでは、measurements という名前の変数を含む想定の sample.mat(クラシックファイル)と sample_v73.mat(7.3 ファイル)を使います。これらのコード片は依存パッケージ前提です。指定されたパッケージがインストールされていることを前提としているので、何も入っていないインタプリタではなく、ご自身の環境で実行してください。
SciPy で MATLAB ファイルを読み込む
pip install scipy でライブラリをインストールし、scipy.io.loadmat("sample.mat") を呼び出します。戻り値は辞書で、変数に加えて __header__、__version__、__globals__ というメタデータキーが含まれます。各 MATLAB 変数はワークスペース名をキーにした NumPy 配列になるので、data["measurements"] でその変数を直接取得できます。
形状がおかしく見えるときに知っておきたいオプションが 2 つあります。loadmat に squeeze_me=True を渡すと MATLAB の単一次元が潰され、スカラーはスカラーとして返ります。struct_as_record=False と組み合わせると、構造体のフィールドにネストした配列要素ではなく属性としてアクセスできます。結果を書き戻すには、scipy.io.savemat("out.mat", {"measurements": data["measurements"]}) でクラシック形式の MAT ファイルを作れます。
重要な制限はバージョンの上限です。loadmat が対応するのは 7.2 までの MAT ファイル形式だけです。7.3 のファイルを渡すと、ペイロードが HDF5 のため未対応の形式として報告されます。そのファイルには次のセクションの方法が必要です。MATLAB 側を管理できるなら、save data.mat -v7 で保存すれば loadmat が受け付けるファイルになります。
h5py で MATLAB 7.3 ファイルを読み込む
-v7.3 のファイルは MATLAB ユーザーブロック付きの HDF5 なので、開くだけなら pip install h5py で十分です。h5py.File("sample_v73.mat", "r") で読み取り用に開き、list(f.keys()) で最上位のグループを確認できます。グループは MATLAB 変数ごとに 1 つずつあり、共有されるセルや構造体の内容を保持する #refs# グループもあります。
f["measurements"][()] を読むと、データセットが NumPy 配列として実体化されます。ファイルを開いたのは h5py なので、ここで NumPy はデータを変換しているだけです。実務で重要なレイアウトの注意点が 2 つあります。MATLAB は配列を列優先で書き出すため、2 次元データセットは転置されて返るのが一般的で、f["measurements"][()].T で MATLAB の向きに戻せます。セル配列や構造体は #refs# への HDF5 オブジェクト参照として届くので、各要素を直接読むのではなく f[ref] で参照を解決します。
mat4py で MATLAB ファイルを読み込む
pip install mat4py で、クラシック MAT ファイル向けの小さな API が使えるようになります。from mat4py import loadmat のあと、loadmat("sample.mat") を呼ぶと普通の辞書が返り、数値配列はネストした Python リスト、構造体はネストした辞書になります。NumPy を持ち込まずにデータを純粋な Python 型として扱いたいときに便利です。
mat4py はクラシック形式のリーダーとして扱ってください。7.3 の HDF5 ファイルは開けず、深くネストした、あるいは特殊な MATLAB 構造はきれいに対応付かないことがあるため、あらゆる MAT ファイルの代替にはなりません。複雑なファイルでは、変換結果を scipy.io と照合してから使いましょう。
MATLAB Engine API で MATLAB ファイルを読み込む
MATLAB 本体がインストールされているなら、その Python 向け Engine API が最も忠実度の高い選択肢です。pip で matlabengine をインストールする(または MATLAB 付属のインストーラーを実行する)と matlab.engine が使えるようになり、背後で実際の MATLAB セッションが動きます。eng = matlab.engine.start_matlab() でそのセッションを起動し、eng.load("sample.mat") でファイルのバージョンにかかわらずすべての変数をエンジンのワークスペースに読み込み、使い終わったら eng.quit() で閉じます。値は matlab.double のような MATLAB 型で返り、NumPy では np.asarray で変換できます。
この方法のトレードオフは形式ではなく実用上のものです。エンジンにはライセンス済みの MATLAB インストールと一致するエンジンバージョンが必要で、セッションの起動には数秒かかり、素の Python 環境では動かせません。だからこそこのセクションでは独立したサンプルではなく呼び出しをインラインで示しています。MATLAB がマシンにない限り、ほかのライブラリを使うのが適切な既定です。