使用H5py读取保存为v7.3 .mat文件的Matlab单元格数组

7

我在Matlab中将一个单元数组保存为.mat文件,操作如下:

test = {'hello'; 'world!'};
save('data.mat', 'test', '-v7.3')

如何使用H5py将其作为Python中的字符串列表导入?
我尝试了以下方法:
f = h5py.File('data.mat', 'r')
print f.get('test')
print f.get('test')[0]

这将打印出以下内容:
<HDF5 dataset "test": shape (1, 2), type "|O8">
[<HDF5 object reference> <HDF5 object reference>]

我该如何在Python中取消引用以获取字符串列表['hello', 'world!']
3个回答

11

使用Matlab进行编程:

test = {'Hello', 'world!'; 'Good', 'morning'; 'See', 'you!'};
save('data.mat', 'test', '-v7.3') % v7.3 so that it is readable by h5py

enter image description here

使用Python读取(适用于任意行列数,但假设每个单元格都是字符串):

import h5py
import numpy as np

data = []
with h5py.File("data.mat") as f:
    for column in f['test']:
        row_data = []
        for row_number in range(len(column)):            
            row_data.append(''.join(map(unichr, f[column[row_number]][:])))   
        data.append(row_data)

print data
print np.transpose(data)

输出:

[[u'Hello', u'Good', u'See'], [u'world!', u'morning', u'you!']]

[[u'Hello' u'world!']
 [u'Good' u'morning']
 [u'See' u'you!']]

在pandas\python\scipy中有没有更好的解决方案,以避免这种丑陋的情况? - Hanan Shteingart
Scipy不支持v7.3。关于pandas我不清楚。 - Franck Dernoncourt

7
这个答案应该被看作是对Franck Dernoncourt回答的补充,它完全适用于包含“平坦”数据的所有单元数组(对于版本7.3及以上的mat文件)。
我遇到了一个我有嵌套数据的情况(例如,在命名的单元数组内部有1行单元数组)。我通过以下方式获取到了这些数据:
# assumption:
# idx_of_interest specifies the index of the cell array we are interested in
# (at the second level)

with h5py.File(file_name) as f:
    data_of_interest_reference = f['cell_array_name'][idx_of_interest, 0]
    data_of_interest = f[data_of_interest_reference]

这个方法适用于嵌套数据的原因: 如果你观察想要获取更深层次数据的数据集的类型,你会发现它是 'h5py.h5r.Reference'。为了实际获取引用所指向的数据,你需要将该引用提供给文件对象


4
我知道这是一个老问题。但我找到了一个包来解决这个问题: hdf5storage 它可以通过pip安装,对于python 3.6和7.3之前的matlab文件都很好用。对于较旧的文件,根据文档,它会调用scipy.io.loadmat

你能分享一下你用来加载字符串数组的代码吗? - Tulkkas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接