.m matlabファイル内で宣言された行列からnumpy配列を作成する

同僚は、Numpyと分析したいデータファイルをいくつか残しました。

それぞれのファイルはmatlabファイルで、 data.m という形式であり、次のような書式設定をしています。

values = [-24.92 -23.66 -22.55 ;
-24.77 -23.56 -22.45 ;
-24.54 -23.64 -22.56 ;
];

これはmatlabによって使用される典型的な明示的なマトリックス作成構文です。

私の質問です:これらのファイルからnumpy配列を作成する最も実用的な方法は何でしょうか?

私は "brute force"や "quick and dirty"のソリューションについて考えることができますが、より単純なものがあれば、numpyや他のモジュールからの標準関数のように、むしろ使いたいと思います。

編集:私のファイルに NaN の値が含まれている可能性があるので、 numpy.loadtxt の代わりに numpy.genfromtxt コード>。私はすぐに私の最終的なコードを含める予定です。

助けてくれてありがとう!

編集:私は正規表現を使用して [] の間ですべてを取得し、NaNを処理するために genfromtxt を使用してnumpy配列を作成する次のコードで終わりました。より短い解決策はStringIOを必要としない fromstring メソッドを使用することですが、これはNaNを処理できず、データにはNaN:oP

#!/usr/bin/env python
# coding: utf-8

import numpy, re, StringIO

with open('data.m') as f:
    s = re.search('\[(.*)\]', f.read(), re.DOTALL).group(1)
    buf = StringIO.StringIO(s)
    a = numpy.genfromtxt(buf, missing_values='NaN', filling_values=numpy.nan)
2

2 答え

ここには2つのオプションがありますが、いずれも組み込まれていません。

おそらく受け入れられない解決策

このソリューションは、おそらくあなたの「迅速かつ汚れた」カテゴリに分類されますが、次のソリューションにつながるのに役立ちます。

values = []、最後の行(]; )を削除し、すべての;

-24.92 -23.66 -22.55 
-24.77 -23.56 -22.45 
-24.54 -23.64 -22.56 

次に、numpyの loadtxt を次のように使用できます。

>>> import numpy as np
>>> A = np.loadtxt('data.m')

>>> A
array([[-24.92, -23.66, -22.55],
       [-24.77, -23.56, -22.45],
       [-24.54, -23.64, -22.56]])

あなたが認められるかもしれない解決策

このソリューションでは、入力データをnumpy loadtxt が好きな形式(実際は上記と同じ形式)に変換するメソッドを作成します。

import StringIO
import numpy as np

def convert_m(fname):
    with open(fname, 'r') as fin:
        arrstr = fin.read()
    arrstr = arrstr.split('[', 1)[-1] # remove the content up to the first '['
    arrstr = arrstr.rsplit(']', 1)[0] # remove the content after ']'
    arrstr = arrstr.replace(';', '\n') # replace ';' with newline
    return StringIO.StringIO(arrstr)

これで、次のことを行います。

>>> np.loadtxt(convert_m('data.m'))
array([[-24.92, -23.66, -22.55],
       [-24.77, -23.56, -22.45],
       [-24.54, -23.64, -22.56]])
2
追加された
あなたの答えは、私が考えていたものの多かれ少なかれでした。今日私はすでに疲れていますが、明日は私が一番良いものを見つけようとします。また、私の質問はジェネリックメソッドにプロンプ​​トを表示するので、良い汎用メソッドについて考えるつもりですが、これらの場合は loadtxt を使用する必要があります。ありがとう、今受け入れて!
追加された 著者 heltonbiker,

イテレータを np.genfromtxt に送ることができます:

import numpy as np
import re

with open(filename, 'r') as f:
    lines = (re.sub(r'[^-+.0-9 ]+', '', line) for line in f)
    arr = np.genfromtxt(lines)

print(arr)

収量

[[-24.92 -23.66 -22.55]
 [-24.77 -23.56 -22.45]
 [-24.54 -23.64 -22.56]]

Thanks to Bitwise for clueing me in to this answer.

1
追加された
実際に言及したファイルは、matlabスクリプトの中にロード可能なmatlab変数を含む.matファイルです。私が持っているファイルは(残念ながら).mファイルです。これにはmatlabのソースコードが含まれています(つまり、スクリプトです)。 numpyではなくmatlabを使用していた場合は、実行中のスクリプトの中で.mファイルを "インポート"して、グローバル名前空間に values という名前の行列を作成します。ナンシーを使用して、so ...:o(
追加された 著者 heltonbiker,
それは非常に専門的な答えです。私はその力を理解する時間が必要ですが、確かにそれは私にいくつかのより深い洞察を与えました。どうもありがとうございました!
追加された 著者 heltonbiker,