最近pythonのコーディングに慣れてきて、レポート作成とかグラフ描写、統計解析とかもpythonとRに集約することができてきました。
プログラミングをやり始めたころは主にMATLABをメインで使っていました。MATLAB自体は直感的で使いやすくてコードも簡単だしいいなーと思っていたのですが、最近は拡張性の高さとトラブルシューティングやエラーの解決の部分の観点から、pythonの方に軍配が上がるなーと個人的に感じています。
しかしMATLABの便利でかなり良いなと思う点として、struct構造の変数を簡単に用意してmatファイルで保存できる点だと思います。csvとかテキストファイルで変数を保存しようとすると行列が合っていなけばならないとかでよくエラーを吐かれるのですが、matファイルで保存してしまえば、その辺は解決できてしまいます。
そんな感じで昔はMATLABでコードを書いて、解析結果とか処理した生のデータをmatファイルで保存して使っていたのですが、そういった昔のデータをpythonで使う必要が出てくる場面が最近出てきました。
調べてみると、pythonでもmatファイルを読み込むことができるようなので、今回はpythonでmatファイルを読み込むために必要な環境設定や変数の取り出し方法について紹介していこうと思います。
pythonでmatファイルを読み込むときにはh5pyモジュールを使う
matファイルをpythonで読み取る際には、h5pyモジュールを使います。これは通常のAnacondaのデフォルトのパッケージには含まれていないので、自分自身でインストールする必要があります。
方法は簡単です。スタート画面からAnacondaのフォルダを開いて「Anaconda Prompt」を開きます。
そうして開かれたコマンドプロンプトに「conda install h5py」と入れればインストールされます。うまくインストールされないときは「pip install h5py」でもいいかもしれません。
これで、matファイルをpythonで扱う準備ができました。
実際にh5pyモジュールを使ってmatファイルを読み込んでみる
import h5py
import numpy as np
import glob
#必要なモジュールのインポート
mat_filename = glob.glob("*.mat")#同じディレクトリ内のmatファイル名のリストを取得
data = data = h5py.File(mat_filename[0],"r")
とりあえずh5pyモジュールでmatファイルを読み込むコードはこんな感じです。データのファイル名の取得の部分は必要に応じてカスタマイズしてください。mat_filename[]の中の数字は任意です。リストの中で読み込みたいファイル名のインデックスの数字を入れるようにしましょう。
私はいちいちmatファイルのファイル名(○○.matみたいな)を手打ちしたくはないので、grob.grob関数で自動で同じディレクトリ内のmatファイル名のリストを取得するようにしています。
ちなみにgrob.grobの関数の中をこんな風にすると違うディレクトリ内のmatファイル名を取得することができます。
import h5py
import glob
mat_filename = glob.glob("rawdata/matfile/*.mat")
#同じディレクトリ内のmatファイル名のリストを取得
例えばこんな感じの書き方にすると、「同じディレクトリ内のrawdataという名前のフォルダの中のさらにmatfileというフォルダの中にあるmatファイルのファイル名をリスト化する」といった処理になります。
h5pyで読み込んだ後は個別に変数を抽出する
h5pyでmatファイルを読み取っただけでは変数を使うことができません。あくまでもこの段階では、構造化された一つのデータを読み込んだだけです。ここから読み込んだmatファイルの中身をバラして変数化しましょう。
import h5py
import numpy as np
import glob
#必要なモジュールのインポート
mat_filename = glob.glob("*.mat")
#同じディレクトリ内のmatファイル名のリストを取得
data = data = h5py.File(mat_filename[0],"r")
#h5pyでmatファイルの読み込み
a = np.array(data['a']).T
b = np.array(data['b']).T
#個別の変数の抽出
先ほどのコードに変数を抽出したものがこちらになります。この例では、仮にmatファイルの中に変数名aとbと定義されたものが入っているという想定です。なのでこの部分はmatファイルにどんな変数名のものが含まれているかで変わりますので、個人でカスタマイズしてつかってください。
データ解析をする場合には変数を抽出した後は、計算処理だったり、データのトリミングをすることがほとんどだと思うので、この段階でnumpy配列(もしくはpandas)にしてしまってもいいと思います。
またデータによっては思った通りの形になっていないこともあるので、必要に応じて.Tの転置処理をするようにしましょう。
matファイルはマジで便利。なんでもデータ格納できる。
やはり個人的にいろいろデータを使っているとmatファイルの形式は非常に便利です。主にMATLABを使って解析をしている人が、他の言語に行かないのもなんとなくわかります。
pythonでもこういう感じでmatファイルを読めると、MATLABメインで使っている人のデータとも互換できるので、使い勝手が一層よくなりますね。
またpythonで解析したデータも実はmatファイルにすることができるのでそれもできるとさらに互換性良くデータを扱うことができますね。おまけにはなりますが、pythonでmatファイルを作成する方法について紹介しておこうと思います。
pythonでmatファイルを作成する際にはscipyを使う
pythonでmatファイルを作成する場合には、今まで使っていたh5pyは使用せず、scipyを使用します。scipyは主に波形処理だったりの部分で使うことが多いモジュールですが、matファイル作成にも多いに役に立ちます。
具体的なコードはこんな感じです。
import numpy as np
import scipy.io as sio
np.savez("data.npz", a, b)
a = np.array([1,2,3,4,5])
b = np.array([6,7,8,9,10])
data1 = np.load('data.npz')
sio.savemat('data.mat', mdict={'a':data1['arr_0'],'a':data1['arr_1']})
pythonでmatファイルを作る場合には、npzファイルを経由します。npzファイルはpythonでいうところのmatファイルみたいなものです。もしかしたらmatlabでもnpz ファイルを直接読み取ることができるかもしれません(それができる仕様だったらすみません)
npzファイルを作るコードはインポートが終わって最初の行です。aとbの変数を格納した構造体配列のdata1.npzを作るといったイメージです。このaとbの部分は入れたいデータによって変わります。
その後はnpzファイルを読み取ってそのデータをmatファイルとして保存するといった感じになります。arr_0というのは変数の一つ目、arr_1は変数の二つ目といった意味です。日本語でこの行で何をしているかを説明すると「data1の変数の一つ目をa、二つ目をbという変数名で、data.matとして保存する」といった内容になります。
わけわかんない変数に見えるけどひも解くと簡単にみえますね。