将 matlab.double 数组转换为 python 数组

问题描述 投票:0回答:4

我正在使用 matlab python 引擎来访问 python 中的 matlab 项目中的数据。这工作得很好,但我确实在 python 中有效使用 matlab 数组时遇到问题。例如,我想要一个来自 matlab 的数组,我使用(eng 代表 matlab 引擎):

x = eng.eval(arg)

我得到的是一个 matlab.double 数组,如下所示:

matlab.double([[1.0,2.0],[4.0,3.0],[2.0,5.0]])

看起来还不错。让我们尝试捕获一个条目:

>>> x[2][1]
5.0

耶!整排怎么样?

>>> x[0]
matlab.double([1.0,2.0])

.. 好吧,至少它是一行,但我没有找到“matlab.double”前缀.. 列怎么样?

>>> x[:][0]
matlab.double([1.0,2.0])

等等,什么?我尝试选择所有行,然后选择每行的第一个元素,但我只得到该行。事实上:

x[i] == x[:][i] == x[i][:]

因此,基本上出现了两个问题:选择一行给我带来了不需要的“matlab.double”前缀,而选择列(个人更重要)根本不起作用。这里有什么建议吗? 我现在所做的是重新读取每个值并将其安全地放入一个新的 python 数组中:

c = [[] for _ in range(len(x[0]))]
for i in range(len(x[0])):
    for j in range(len(x)):
        c[i].append(x[j][i])

这可行,但有一个问题:随着数据的增长,它会极大地减慢代码速度。当然,如果它们实际上已经存储在 x 中,那么重新读取每个条目感觉并不好。

感谢您阅读这篇长文,我只是假设我解释得更多一点,因为可能只有少数人使用 python matlab 引擎。

python arrays performance matlab multidimensional-array
4个回答
2
投票

一种更通用的方法,我现在正在高效地使用它,还允许我在需要时对值进行舍入(但要小心,舍入需要更多的计算时间):

from math import log10, floor

def convert(self, x, ROUND=0):

    conv = []

    for _ in range(x.size[0]):
        lst = x._data[_::x.size[0]].tolist()

        if ROUND is not 0:
            lst = [self.round_sig(elem, ROUND) if elem != 0 and
                   elem == elem else elem for elem in lst]

        conv.append(lst)

    return conv

def round_sig(self, x, sig=2):
    return round(x, sig-int(floor(log10(abs(x))))-1)

1
投票

根据下面讨论的输入,我设法找到了一个合理的方法:

c = []
for _ in range(x.size[1]):
    c.append(x._data[_*x.size[0]:_*x.size[0]+x.size[0]].tolist())
return c

这样,该命令大约需要 0.009 秒,而不是之前的 0.045 秒。使用 zip 功能大约需要 0.022 秒。非常感谢,代码现在运行速度快了 5 倍!

为了澄清:

x.size[i]
给出了
matlab.double
数组的大小。
x._data
给出类型的一维数组:

array('d', [1.0,2.0,4.0 ... ])

因此它包含一个 tolist() 方法来获取我需要的实际列表。


0
投票

有一种更简洁(和Pythonic)的方法来使用列表理解来提取列,并且它还可以立即以Python浮点数列表的形式提供输出:

>>> x = matlab.double([[1.0,2.0],[4.0,3.0],[2.0,5.0]])
>>> [d[0] for d in x]
[1.0, 4.0, 2.0]

0
投票

对于这个问题的新手,

numpy
是正确的选择,你可以选择从那里转换为纯Python列表:

import numpy as np

y = np.asarray(x).tolist()
© www.soinside.com 2019 - 2024. All rights reserved.