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

查看:70
本文介绍了提高将 numpy 数组转换为 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 秒,这对于一个转换来说似乎太多了,除了使 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 数组

查看文件夹 PYTHONPATHLibsite-packagesmatlab\_internal 中的文件 mlarray_sequence.py.在那里您将找到 MATLAB 数组对象的构造.性能问题来自于在 generic_flattening 函数中使用循环复制数据.

Take a look at the file mlarray_sequence.py in the folder PYTHONPATHLibsite-packagesmatlab\_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. 备份原始文件以防出现问题.

  1. Make a backup of the original file in case something goes wrong.

import numpy as np 添加到文件开头的其他导入

Add import numpy as np to the other imports at the beginning of the file

在第 38 行你应该找到:

In line 38 you should find:

init_dims = _get_size(initializer)

将其替换为:

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)
    

    将其替换为:

    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 double 的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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