提高将numpy数组转换为MATLAB的性能 [英] Improve performance of converting numpy array to MATLAB double
问题描述
从Python调用MATLAB势必会降低性能,而我可以通过用Python重写(很多)代码来避免这种性能下降.但是,这对我来说不是一个现实的选择,但是令我烦恼的是,效率的巨大损失在于从numpy数组到MATLAB double的简单转换.
Calling MATLAB from Python is bound to give some performance reduction that I could avoid by rewriting (a lot of) code in Python. However, this isn't a realistic option for me, but it annoys me that a huge loss of efficiency lies in the simple conversion from a numpy array to a MATLAB double.
我说的是从data1到data1m的以下转换,其中
I'm talking about the following conversion from data1 to data1m, where
data1 = np.random.uniform(low = 0.0, high = 30000.0, size = (1000000,))
data1m = matlab.double(list(data1))
此处matlab.double来自MathWorks自己的MATLAB软件包/引擎.第二行代码在我的系统上花费20 s,对于转换而言,这看起来实在太多了,除了将数字设为可食用"以进行MATLAB之外,它实际上没有做任何其他事情.
Here matlab.double comes from Mathworks own MATLAB package / engine. The second line of code takes 20 s on my system, which just seems like too much for a conversion that doesn't really do anything other than making the numbers 'edible' for MATLAB.
所以基本上我正在寻找与给定的此处相反的技巧,该技巧可用于将MATLAB输出转换为Python.
So basically I'm looking for a trick opposite to the one given here that works for converting MATLAB output back to Python.
推荐答案
有效地传递numpy数组
看看文件夹PYTHONPATH\Lib\site-packages\matlab\_internal
中的文件mlarray_sequence.py
.在那里,您将找到MATLAB数组对象的构造.性能问题来自generic_flattening
函数中带有循环的数据复制.
Take a look at the file mlarray_sequence.py
in the folder PYTHONPATH\Lib\site-packages\matlab\_internal
. There you will find the construction of the MATLAB array object. The performance problem comes from copying data with loops within the generic_flattening
function.
为避免这种情况,我们将对文件进行一些编辑.此修复程序应适用于复杂和非复杂的数据类型.
To avoid this behavior we will edit the file a bit. This fix should work on complex and non-complex datatypes.
- 对原始文件进行备份,以防出现问题.
- 在文件开头的其他导入中添加
import numpy as np
-
在第38行中,您应该找到:
- Make a backup of the original file in case something goes wrong.
- Add
import numpy as np
to the other imports at the beginning of the file In line 38 you should find:
init_dims = _get_size(initializer) # replace this with
try:
init_dims=initializer.shape
except:
init_dims = _get_size(initializer)
在第48行中,您应该找到:
In line 48 you should find:
if is_complex:
complex_array = flat(self, initializer,
init_dims, typecode)
self._real = complex_array['real']
self._imag = complex_array['imag']
else:
self._data = flat(self, initializer, init_dims, typecode)
#Replace this with:
if is_complex:
try:
self._real = array.array(typecode,np.ravel(initializer, order='F').real)
self._imag = array.array(typecode,np.ravel(initializer, order='F').imag)
except:
complex_array = flat(self, initializer,init_dims, typecode)
self._real = complex_array['real']
self._imag = complex_array['imag']
else:
try:
self._data = array.array(typecode,np.ravel(initializer, order='F'))
except:
self._data = flat(self, initializer, init_dims, typecode)
现在,您可以将numpy数组直接传递给MATLAB数组创建方法.
Now you can pass a numpy array directly to the MATLAB array creation method.
data1 = np.random.uniform(low = 0.0, high = 30000.0, size = (1000000,))
#faster
data1m = matlab.double(data1)
#or slower method
data1m = matlab.double(data1.tolist())
data2 = np.random.uniform(low = 0.0, high = 30000.0, size = (1000000,)).astype(np.complex128)
#faster
data1m = matlab.double(data2,is_complex=True)
#or slower method
data1m = matlab.double(data2.tolist(),is_complex=True)
MATLAB数组创建中的性能提高了15倍,并且该接口现在更易于使用.
The performance in MATLAB array creation increases by a factor of 15 and the interface is easier to use now.
这篇关于提高将numpy数组转换为MATLAB的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!