2013-10-11 13 views
12

私はstruct配列MathWorks社のMATLABで作成され、V7.3形式マットファイルに保存されているがあります。h5py経由でv7.3マットファイルを読むには?

struArray = struct('name', {'one', 'two', 'three'}, 
        'id', {1,2,3}, 
        'data', {[1:10], [3:9], [0]}) 
save('test.mat', 'struArray', '-v7.3') 

今私はh5pyを使ってPythonを経由して、このファイルを読みたい:

data = h5py.File('test.mat') 
struArray = data['/struArray'] 

私は見当がつかない私は通訳を発射し、01でhelpを実行することによって開始する

for index in range(<the size of struArray>): 
    elem = <the index th struct in struArray> 
    name = <the name of elem> 
    id = <the id of elem> 
    data = <the data of elem> 
+0

このため、実際の解決策を見つけますか? – Pastafarian

+0

私は同様の疑問があり、部分的な解決策がありました。http://stackoverflow.com/questions/29852481/reading-all-variables-in-a-mat-file-with-python-h5py/29856030#29856030 – CodyF

答えて

0

Matlabの7.3ファイル形式はh5pyで動作するように非常に簡単ではありません。これはHDF5のリファレンスに依存しています(cf. h5py documentation on references

>>> import h5py 
>>> f = h5py.File('test.mat') 
>>> list(f.keys()) 
['#refs#', 'struArray'] 
>>> struArray = f['struArray'] 
>>> struArray['name'][0, 0] # this is the HDF5 reference 
<HDF5 object reference> 
>>> f[struArray['name'][0, 0]].value # this is the actual data 
array([[111], 
     [110], 
     [101]], dtype=uint16) 

struArray(i).idを読み取るには:

>>> f[struArray['id'][0, 0]][0, 0] 
1.0 
>>> f[struArray['id'][1, 0]][0, 0] 
2.0 
>>> f[struArray['id'][2, 0]][0, 0] 
3.0 

注意そのMatlabの店舗番号をサイズのアレイとして(1,1)、したがって最終[0, 0]番号を取得します。 struArray(i).data読むに

struArray(i).nameを読むには

>>> f[struArray['data'][0, 0]].value 
array([[ 1.], 
     [ 2.], 
     [ 3.], 
     [ 4.], 
     [ 5.], 
     [ 6.], 
     [ 7.], 
     [ 8.], 
     [ 9.], 
     [ 10.]]) 

を、文字列に整数の配列を変換する必要がある:

>>> f[struArray['name'][0, 0]].value.tobytes()[::2].decode() 
'one' 
>>> f[struArray['name'][1, 0]].value.tobytes()[::2].decode() 
'two' 
>>> f[struArray['name'][2, 0]].value.tobytes()[::2].decode() 
'three' 
0

struArrayから一つの構造体のデータ1を取得する方法。それはあなたが始めるための十分な情報を与える必要があります。それに失敗した場合は、__dict__属性を使用して、任意のPythonオブジェクトの属性をprintでダンプできます。

0

私は申し訳ありませんが、Matlabの外部から細胞/構造の内容を取得するのはかなり難しいと思います。作成されたファイル(HDFViewなど)を表示すると、相互参照が多く、処理を進める明白な方法がないことがわかります。

単純な数値配列に固執すればうまく動作します。数値配列を含む小規模なセル配列を持っている場合は、通常は数行しかない別々の変数(cellcontents1、cellcontents2など)に変換して、それらを直接保存してロードすることができます。私は答えた何thatsのあなたが質問にh5pyを指定したが、scipy.io.loadmatであなたは、元の変数を取得することができなければならないことを言及する価値がnumpyのように変換:だからあなたの例では、私はVARS name1, name2, name3, id1, id2, id3 ...など

EDITでファイルを保存します等価物(例えばオブジェクト配列)。

+4

ありがとうとにかく!私はこの問題に数日苦労している。私はいつも本当の価値よりもむしろ ''のようなものを得ました。しかし、 'scipy.io.loadmat'はv7.3フォーマットのmatファイルでは動作しません。 – Eastsun

-1

Matlab 7.3とh5pyでは実際に問題があります。 私のやり方は、タイプをnumpyアレイに変換することです。 例えば、

np.array(data['data']) 

'data'フィールドを使用して問題を解決します。

+0

動作しません。既存の配列の上に別の配列レイヤーを追加するだけです。例えば。 'array([HDF5オブジェクト参照]、]、dtype =オブジェクト)'そして、既存のデータ型は 'h5py._hl.dataset.Dataset'です – Pastafarian

2

visitまたはvisititemsh5pyファイルの全体的な構造を見ての簡単な方法です:

fs['struArray'].visititems(lambda n,o:print(n, o)) 

私はオクターブsave -hdf5によって生成されたファイルでこれを実行すると、私が手:

type <HDF5 dataset "type": shape(), type "|S7"> 
value <HDF5 group "/struArray/value" (3 members)> 
value/data <HDF5 group "/struArray/value/data" (2 members)> 
value/data/type <HDF5 dataset "type": shape(), type "|S5"> 
value/data/value <HDF5 group "/struArray/value/data/value" (4 members)> 
value/data/value/_0 <HDF5 group "/struArray/value/data/value/_0" (2 members)> 
value/data/value/_0/type <HDF5 dataset "type": shape(), type "|S7"> 
value/data/value/_0/value <HDF5 dataset "value": shape (10, 1), type "<f8"> 
value/data/value/_1 <HDF5 group "/struArray/value/data/value/_1" (2 members)> 
... 
value/data/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/id <HDF5 group "/struArray/value/id" (2 members)> 
value/id/type <HDF5 dataset "type": shape(), type "|S5"> 
value/id/value <HDF5 group "/struArray/value/id/value" (4 members)> 
value/id/value/_0 <HDF5 group "/struArray/value/id/value/_0" (2 members)> 
... 
value/id/value/_2/value <HDF5 dataset "value": shape(), type "<f8"> 
value/id/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/name <HDF5 group "/struArray/value/name" (2 members)> 
... 
value/name/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 

この5月MATLAB 7.3が生成するものと同じではありませんが、構造の複雑さの考え方を示します。

より洗練されたコールバックは値を表示することができ、Pythonオブジェクト(辞書、リストなど)を再作成するための出発点になります。

def callback(name, obj): 
    if name.endswith('type'): 
     print('type:', obj.value) 
    elif name.endswith('value'): 
     if type(obj).__name__=='Dataset': 
      print(obj.value.T) # http://stackoverflow.com/questions/21624653 
    elif name.endswith('dims'): 
     print('dims:', obj.value) 
    else: 
     print('name:', name) 

fs.visititems(callback) 

は生成します。

name: struArray 
type: b'struct' 
name: struArray/value/data 
type: b'cell' 
name: struArray/value/data/value/_0 
type: b'matrix' 
[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]] 
name: struArray/value/data/value/_1 
type: b'matrix' 
[[ 3. 4. 5. 6. 7. 8. 9.]] 
name: struArray/value/data/value/_2 
type: b'scalar' 
0.0 
dims: [3 1] 
name: struArray/value/id 
type: b'cell' 
name: struArray/value/id/value/_0 
type: b'scalar' 
1.0 
... 
dims: [3 1] 
name: struArray/value/name 
type: b'cell' 
name: struArray/value/name/value/_0 
type: b'sq_string' 
[[111 110 101]] 
... 
dims: [3 1] 
関連する問題