提高将numpy数组转换为MATLAB的性能 [英] Improve performance of converting numpy array to MATLAB double

查看:403
本文介绍了提高将numpy数组转换为MATLAB的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从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.

  1. 对原始文件进行备份,以防出现问题.
  2. 在文件开头的其他导入中添加import numpy as np
  3. 在第38行中,您应该找到:

  1. Make a backup of the original file in case something goes wrong.
  2. Add import numpy as np to the other imports at the beginning of the file
  3. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆