Я думаю, что могу воссоздать ваш массив с помощью
In [38]: array=np.array
In [43]: data = np.zeros((1,1),object)
In [44]: data[0,0] = array([[(array([[488.42954942, 345.62261032]]), array([[461
...: .57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), arra
...: y([[492.42954942, 384.62261032]]))]],
...: dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
In [45]: data
Out[45]:
array([[array([[(array([[488.42954942, 345.62261032]]), array([[461.57045058, 348.37738968]]), array([[465.57045058, 387.37738968]]), array([[492.42954942, 384.62261032]]))]],
dtype=[('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])]],
dtype=object)
Это (1,1) массив dtype объекта, который содержит другой массив. Этот массив также имеет (1,1) форму, но с составным типом d (массив structured
).
In [51]: data.shape, data.dtype
Out[51]: ((1, 1), dtype('O'))
В MATLAB все равно 2d. loadmat
имеет параметр squeeze
, который может указывать на удаление ненужных измерений. Без этого мы получаем множество (1,1) массивов.
Объекты MATLAB, такие как cell
и struct
, возвращаются в виде массивов типа d объекта. Обычные матрицы MATLAB возвращаются числовыми массивами numpy
.
Мы можем извлечь один элемент из data
с двумерным индексом (более идиоматическим, чем data[0][0]
):
In [52]: data1 = data[0,0]
In [53]: data1.shape, data1.dtype
Out[53]: ((1, 1), dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')]))
item()
также работает для удаления одного элемента из массива:
In [54]: data.item().dtype
Out[54]: dtype([('a', 'O'), ('b', 'O'), ('c', 'O'), ('d', 'O')])
На этом уровне массив представляет собой структурированный массив с 4 (именованными) полями, каждый объект dtype.
Поля(обычно) индексируются по имени. Но, будучи объектом dtype, у нас есть еще один слой:
In [74]: data1['a']
Out[74]: array([[array([[488.42954942, 345.62261032]])]], dtype=object)
In [75]: data1['a'].item()
Out[75]: array([[488.42954942, 345.62261032]])
In [76]: data1['a'].item().squeeze()
Out[76]: array([488.42954942, 345.62261032])
Идея @ aparpara в использовании к tolist()
может быть самым чистым способом извлечения этих полей вложенных объектов:
In [85]: data1.tolist()
Out[85]:
[[(array([[488.42954942, 345.62261032]]),
array([[461.57045058, 348.37738968]]),
array([[465.57045058, 387.37738968]]),
array([[492.42954942, 384.62261032]]))]]
Вкл. структурированный массив tolist()
создает список (или вложенный список) кортежей, один кортеж на «запись» массива.
Затем мы можем использовать np.array
или concatenate
, чтобы объединить массивы в один,и squeeze
для удаления лишних измерений:
In [87]: np.array(data1.tolist()).squeeze()
Out[87]:
array([[488.42954942, 345.62261032],
[461.57045058, 348.37738968],
[465.57045058, 387.37738968],
[492.42954942, 384.62261032]])
Источник MATLAB не является простой двумерной числовой матрицей. Так что перевод на другой язык тоже не будет простым. Некоторые параметры loadmat
могут упростить структуру возврата. Кроме того, нам нужно пройти вниз по слоям с индексированием item
или [0,0]
.