2017-07-18 58 views
1

我想在python中加载.mat文件。用scipy.loadmat加载nested defaultdict

import collections 
import scipy.io 

out_o = collections.defaultdict(list) 
out_t = collections.defaultdict(list) 
out_o['o1'] = {'x':[1,2,3], 'y':[4,5,6]} 
out_o['o2'] = {'x':[7,8,9], 'y':[10,11,12]} 
out_t['t'] = out_o 
scipy.io.savemat('test.mat', out_t) 

我怎样才能重建从文件test.matout_t没有硬编码的out_o键: 该文件是这样产生的?

我设法与键:

input = scipy.io.loadmat('test.mat', squeeze_me=True, struct_as_record=True) 
print(list(input['t'].dtype.names)) 

[ '氧气', '01']

但我如何访问数据?

print(input['t']) 

打印:

((阵列([7,8,9]),阵列([10,11,12])),(阵列([1,2,3] ),阵列([4,5,6])))

那作为如我设法到xy靠近...


编辑:

感谢hpauljs的回答,我设法解决了我的问题。

我不可能硬编码oi S,所以我用dtype.fields.keys()

input = scipy.io.loadmat('test.mat') 
objs = list(input['t'].dtype.fields.keys()) 
in_o = collections.defaultdict(list) 
in_t = collections.defaultdict(list) 
for i in objs: 
    in_o[i]={'x': list(input['t'][i][0,0]['x'][0,0][0]),'y': list(input['t'][i][0,0]['y'][0,0][0])} 
in_t['t'] = in_o 

print(in_t == out_t) 
+0

什么你没有'struct_as_record'参数? 'savemat'将数据压缩成与matlab兼容的结构。它不是为了腌制蟒蛇而设计的。 – hpaulj

回答

1

节省

In [409]: out_t 
Out[409]: 
defaultdict(list, 
      {'t': defaultdict(list, 
         {'o1': {'x': [1, 2, 3], 'y': [4, 5, 6]}, 
          'o2': {'x': [7, 8, 9], 'y': [10, 11, 12]}})}) 

,并取回

In [410]: R = io.loadmat('test.mat') 
In [411]: R 
Out[411]: 
{'__globals__': [], 
'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Tue Jul 18 09:32:39 2017', 
'__version__': '1.0', 
't': array([[ (array([[(array([[1, 2, 3]]), array([[4, 5, 6]]))]], 
     dtype=[('x', 'O'), ('y', 'O')]), array([[(array([[7, 8, 9]]), array([[10, 11, 12]]))]], 
     dtype=[('x', 'O'), ('y', 'O')]))]], 
     dtype=[('o1', 'O'), ('o2', 'O')])} 

R['t']是(1,1 )有2个字段的数组,dtype([('o1', 'O'), ('o2', 'O')])

In [417]: R['t']['o1'] 
Out[417]: 
array([[ array([[(array([[1, 2, 3]]), array([[4, 5, 6]]))]], 
     dtype=[('x', 'O'), ('y', 'O')])]], dtype=object) 

这是(1,1)的对象阵列;元素是一个具有2个字段的(1,1)阵列

In [424]: R['t']['o1'][0,0]['x'][0,0] 
Out[424]: array([[1, 2, 3]]) 

要与matlab兼容,所有数组都是2d。字典保存为结构化数组,每个键一个字段。

squeeze_me索引有点不同。 (1,1)对象数组已被替换为()(0d)对象数组。

In [437]: R['t']['o1'].item()['x'].item() 
Out[437]: array([1, 2, 3]) 

正如我评论。 savemat节省了matlab兼容结构。如果要保存并重新加载Python对象,请使用pickle

加载该文件中的八度给人一种结构,t

>> t 
t = 
    scalar structure containing the fields: 
    o1 = 
     scalar structure containing the fields: 
     x = 
      1 2 3 
     y = 
      4 5 6 
    o2 = 
     scalar structure containing the fields: 
     x = 
      7 8 9 
     y = 
      10 11 12 

np.save节省的Python与他们的泡菜的对象后,在对象D型阵列第一包裹他们:

In [467]: np.save('test.npy', out_t) 
In [468]: np.load('test.npy') 
Out[468]: array(defaultdict(<class 'list'>, {'t': defaultdict(<class 'list'>, {'o1': {'x': [1, 2, 3], 'y': [4, 5, 6]}, 'o2': {'x': [7, 8, 9], 'y': [10, 11, 12]}})}), dtype=object) 
In [469]: _.item() 
Out[469]: 
defaultdict(list, 
      {'t': defaultdict(list, 
         {'o1': {'x': [1, 2, 3], 'y': [4, 5, 6]}, 
          'o2': {'x': [7, 8, 9], 'y': [10, 11, 12]}})}) 
+0

感谢您的详细解答,在您的帮助下我能解决我的问题(请参阅问题编辑) – Jonas