Как эффективно конвертировать массивы MATLAB engine в numpy ndarray?

в настоящее время я работаю над проектом, где мне нужно выполнить некоторые шаги обработки с помощью устаревшего кода Matlab (используя движок Matlab) и остальные в Python (numpy).

Я заметил, что преобразование результатов из Matlab в matlab.mlarray.double в пакете numpy в numpy.ndarray кажется ужасно медленным.

вот пример кода для создания ndarray с 1000 элементами из другого ndarray, списка и mlarray:

import timeit
setup_range = ("import numpy as npn"
               "x = range(1000)")
setup_arange = ("import numpy as npn"
                "x = np.arange(1000)")
setup_matlab = ("import numpy as npn"
                "import matlab.enginen"
                "eng = matlab.engine.start_matlab()n"
                "x = eng.linspace(0., 1000.-1., 1000.)")
print 'From other array'
print timeit.timeit('np.array(x)', setup=setup_arange, number=1000)
print 'From list'
print timeit.timeit('np.array(x)', setup=setup_range, number=1000)
print 'From matlab'
print timeit.timeit('np.array(x)', setup=setup_matlab, number=1000)

, который имеет следующий раз:

From other array
0.00150722111994
From list
0.0705359556928
From matlab
7.0873282467

преобразование занимает около 100 раз больше времени, чем преобразование из списка.

есть ли способ ускорить преобразование?

2 ответов


моменты после публикации вопроса я нашел решение.

для одномерных массивов, доступ только _data свойство массива Matlab.

import timeit
print 'From list'
print timeit.timeit('np.array(x)', setup=setup_range, number=1000)
print 'From matlab'
print timeit.timeit('np.array(x)', setup=setup_matlab, number=1000)
print 'From matlab_data'
print timeit.timeit('np.array(x._data)', setup=setup_matlab, number=1000)

печать

From list
0.0719847538787
From matlab
7.12802865169
From matlab_data
0.118476275533

для многомерных массивов вам нужно изменить массив впоследствии. В случае двумерных массивов это означает вызов

np.array(x._data).reshape(x.size[::-1]).T

ответ Тима отлично подходит для 2D-массивов, но способ адаптировать его к N-мерным массивам-использовать order параметр np.reshape() :

np_x = np.array(x._data).reshape(x.size, order='F')