Конвертировать несколько Python словарей в структурный массив MATLAB с помощью scipy.io savemat - PullRequest
3 голосов
/ 01 мая 2020

Простой вопрос, но тот, который я не могу обернуть вокруг себя. Я использую библиотеку scipy.io для сохранения словарей Python как структур Matlab. Теперь документация библиотеки scipy.io показывает нам, как сделать это для одного Python словаря для одной структуры Matlab:

>>> a_dict = {'field1': 0.5, 'field2': 'a string'}
>>> sio.savemat('saved_struct.mat', {'a_dict': a_dict})

Это звучит достаточно справедливо, и works:

enter image description here

Однако теперь я хочу сделать то же самое для нескольких Python словарей. Я хочу, чтобы они были переведены в структуру Matlab, в которой имена столбцов равны ключам всех словарей (которые, очевидно, являются одинаковыми именами ключей), и я хочу, чтобы каждая строка представляла значения для этих ключей для одного из Словари. Если я вижу это правильно, это называется структурой 1 x K с 10 полями, где K - количество строк (Python Словари), которые я хочу отобразить. поля Пример, показанный ниже:

enter image description here

Хотя я сам совершенно не осведомлен о правильной терминологии Matlab, хорошая душа в комментариях сказала мне, что это должно называться структурным массивом . Я попытался просто создать массив numpy словарей Python, поместить его в пару значений ключа a_dict в приведенном выше примере кода и сохранить его, но безуспешно. В результате получается список всех различных структур вместо одной большой структуры со строками, представляющими значения для каждой отдельной структуры.

Таким образом, я все еще ищу подходящее решение для этой проблемы. Если вам нужны какие-либо дополнительные детали, не стесняйтесь спрашивать в комментариях. Спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

Вот решение:

В Python:

>>> a_dict = {'field1': 0.5, 'field2': 'a string'}
>>> b_dict = {'field1': 1, 'field2': 'another string'}
>>> sio.savemat('saved_struct.mat', {'dict_array':[a_dict,b_dict]})

В MATLAB:

s = load('saved_struct.mat');
struct_array = [s.dict_array{:}];

В результате вы получите массив структуры в MATLAB как желаемый.

struct_array = 

  1×2 struct array with fields:

    field1
    field2
1 голос
/ 01 мая 2020

@ UnbearableLightness имеет самое простое решение, но для пояснения предложения structured array я приведу пример.

Определим структурированный массив:

In [192]: arr = np.array([(0.5,'one'),(0.6,'two'),(0.8,'three')], dtype=[('field1',float),('field2','U10')])                                                                                        

и список словари с одинаковыми полями и данными:

In [194]: dicts = [{'field1':0.5, 'field2':'one'},{'field1':0.6, 'field2':'two'},{'field1':0.8,'field2':'three'}]

In [195]: arr                                                                                          
Out[195]: 
array([(0.5, 'one'), (0.6, 'two'), (0.8, 'three')],
      dtype=[('field1', '<f8'), ('field2', '<U10')])

In [196]: dicts                                                                                        
Out[196]: 
[{'field1': 0.5, 'field2': 'one'},
 {'field1': 0.6, 'field2': 'two'},
 {'field1': 0.8, 'field2': 'three'}]

сохранить и загрузить:

In [197]: io.savemat('ones.mat', {'arr':arr, 'dicts':dicts})                                           
In [198]: io.loadmat('ones.mat')                                                                       
Out[198]: 
{'__header__': b'MATLAB 5.0 MAT-file Platform: posix, Created on: Fri May  1 09:06:19 2020',
 '__version__': '1.0',
 '__globals__': [],
 'arr': array([[(array([[0.5]]), array(['one'], dtype='<U3')),
         (array([[0.6]]), array(['two'], dtype='<U3')),
         (array([[0.8]]), array(['three'], dtype='<U5'))]],
       dtype=[('field1', 'O'), ('field2', 'O')]),
 'dicts': array([[array([[(array([[0.5]]), array(['one'], dtype='<U3'))]],
       dtype=[('field1', 'O'), ('field2', 'O')]),
         array([[(array([[0.6]]), array(['two'], dtype='<U3'))]],
       dtype=[('field1', 'O'), ('field2', 'O')]),
         array([[(array([[0.8]]), array(['three'], dtype='<U5'))]],
       dtype=[('field1', 'O'), ('field2', 'O')])]], dtype=object)}

savemat создал несколько массивов dtype объектов (и полей) и массивы 2d MATLAB.

В октавном сеансе:

>> load ones.mat

arr - это struct array с 2 полями:

>> arr
arr =

  1x3 struct array containing the fields:

    field1
    field2

>> arr.field1
ans =  0.50000
ans =  0.60000
ans =  0.80000
>> arr.field2
ans = one
ans = two
ans = three

dicts - это ячейка со скалярными структурами :

>> dicts
dicts =
{
  [1,1] =

    scalar structure containing the fields:

      field1 =  0.50000
      field2 = one

  [1,2] =

    scalar structure containing the fields:

      field1 =  0.60000
      field2 = two

  [1,3] =

    scalar structure containing the fields:

      field1 =  0.80000
      field2 = three

}

, который может быть преобразован в тот же массив структуры, который показал @Unbearable:

>> [dicts{:}]
ans =

  1x3 struct array containing the fields:

    field1
    field2

>> _.field1
error: '_' undefined near line 1 column 1
>> [dicts{:}].field1
ans =  0.50000
ans =  0.60000
ans =  0.80000
>> [dicts{:}].field2
ans = one
ans = two
ans = three
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...