从Matlab到Python:获取Matlab单元数组值
我刚接触matlab和python,想从matlab的单元数组中用一些值到python里。
我有一个整数的单元数组,执行完这行代码后打印结果,得到的是:
a = loadmat('file.mat')
print a
{'__version__': '1.0', '__header__': 'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011', 'juncForward_c': array([[ [[ [[ ([[30]], **[[91], [87]]**, [[3]], [[2.2455372690184494, 3.6052402625905993, 5.5884470309828833]], [[14.0, 4.0, 15.4]], [[-1, -1, 2]], [[91, 89, 93], [88, 85, 86]], [[500, 500, 5]], [[1, 2, 3]], [[11.133333333333333]], **[[4]]**, [[1]], [[1]], [[1.0], [20.365168528421695]])]]
[[ ([[30]], **[[99], [80]]**, [[3]], [[4.0376480381611373, 2.3561944901923448, 6.0857897473297058]], [[10.0, 15.4, 16.600000000000001]], [[-1, 1, 3]], [[98, 98, 100], [79, 81, 80]], [[500, 6, 33]], [[1, 2, 3]], **[[14]]**, [[2]], [[1]], [[1]], [[2.0], [6.6573267908372973]])]]
然后打印的内容还在继续。
有人能告诉我这个单元数组是怎么排列的吗?(上面的这个有多少维度?)
我还有几个问题:
1) 在这个单元数组里,有两个变量'label'和'coordinates',它们被分配到一个数组/单元里(我不知道用哪个词更准确)——这些值是加粗的。我想在Python里写代码来访问这些值,我该怎么做呢?
2) 为了测试,我尝试了这个 -> juncInfoF = a.get('juncForward_c')
,但当我尝试打印juncInfoF时,它显示'None'。这是为什么呢?我很困惑,因为之前我试过这个是有效的。我甚至可以这样做 -> print juncInfo[0][9][0][0]
,但现在我连这些都做不了了。
2 个回答
如果你的mat文件里只有包含整数或字符串的单元数组,我写了一段通用的代码来处理这个情况。
比如,在matlab里你可以这样做:
names = cell(1, N);
indices = cell(1, N);
for ind=1:N
names{ind} = *some_value*;
indices{ind} = *some_array*;
save('names_and_indices.mat', 'names', 'indices');
在这里你可以找到如何在python中读取这个mat文件的方法。
我想象一下,loadmat('file.mat')
这个函数会返回一个类似于 shelve 的对象,它是从字典(dict)这个类继承来的。我猜你是在使用 scipy.io 里的 loadmat 函数,对吧?
from scipy.io import loadmat
根据 scipy 的文档,loadmat() 只提到它返回一个字典,但我猜在你的例子中,返回的对象 a
是一个打开的 shelve 文件,当 a
被 closed
后,你就无法再访问它的内容了,这可能是因为除了手动调用 a.close()
之外,还有其他原因导致的。
为了避免这种情况,建议在加载数据时,先把所有数据复制到一个真正的字典里:
mat_dict = {}
mat_dict.update(loadmat('file.mat'))
现在你可以从 mat_dict
中获取所有的键和值:
a = mat_dict['juncForward_c']
print(a.shape) # should work now
请注意,只要你在测试和了解 mat_dict 数据的内容,这种做法是有效的。在你的脚本、模型或函数中,通常只会加载你需要的 shelve 字典的一部分,然后明确地关闭文件:
f = loadmat('file.mat')
a = f['juncForward_c']
f.close()
我不确定 with 语句是否有效(shelve 目前还不支持这个),你需要自己测试一下,但它应该能在加载 a
时,即使出现异常也能处理关闭操作:
with loadmat('file.mat') as f:
a = f['juncForward_c']
编辑:从 numpy 数组子类化以添加额外属性
import numpy as np
class MatArray(np.array):
def __init__(self, filepath):
f = loadmat(filepath)
np.array.__init__(self, f['juncForward_c'])
self.version = f['__version__']
self.header = f['__header__']
f.close()
所以现在如果你想让你的数组看起来像 matlab 结构,你可以这样做:
>>> a = MatArray('myfile.mat')
>>> a.header
'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011'
>>> a.shape
等等