如何使用mlabwrap从Python调用带有单元参数的MATLAB函数?

4 投票
2 回答
1750 浏览
提问于 2025-04-17 20:09

我之前很自豪自己成功安装了mlabwrap,但现在我发现它和matlab的单元格(cells)不太兼容。在Python中,列表可以看作是单元格的替代品,所以我想把一个列表输入进去,mlabwrap应该能把它转换成单元格。可惜,似乎并不是这样。

举个例子,我有一个matlab的m文件:

function list_test(x)
display(x);

在Python中,如果我输入

mlab.list_test([[1,2],[3,4]])

我得到的结果是:

x =

1     2
3     4

所以,mlabwrap似乎把我两个嵌套的列表变成了一个2x2的矩阵,这并不是我想要的结果。

当我尝试输入

mlab.list_test([[1,2],[3,4,5]]) 

然后我得到:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/Ben/.virtualenvs/test/lib/python2.7/site-packages/mlabwrap.py", line 607, in mlab_command
    return self._do(name, *args, **update({'nout':nout}, kwargs))
  File "/Users/Ben/.virtualenvs/test/lib/python2.7/site-packages/mlabwrap.py", line 534, in _do
    mlabraw.put(self._session,  argnames[-1], arg)
TypeError: a float is required

显然,这也不行。

如果真的没办法,我想我可以写一些Python代码,把列表转换成几个一维数组,然后通过mlabwrap把这些一维数组传给matlab,再写一些matlab代码把这些一维数组转换成单元格。但这样做太麻烦了,我想知道有没有更简单的方法。mlabwrap能不能帮我做到这一点呢?

这是我设置的详细信息:
操作系统:Mountain Lion (OS X 10.8),
Python版本:2.7,
Matlab版本:2010b,
mlabwrap版本:1.1

2 个回答

0

如果几年后有人看到这个,其实对单元数组和字符数组是有基本支持的,你只需要输入这个:

mlab._dont_proxy["cell"] = True

在使用返回单元数组或字符数组的matlab命令之前。这是在https://github.com/aweinstein/mlabwraphttps://github.com/cpbotha/mlabwrap-purepy上测试过的。

1

很遗憾,mlabwrap对单元数组的支持有限;无论是把单元数组传入matlab,还是从matlab接收单元数组,都有一些问题。

下面是你立即想知道的答案:

>>> from mlabwrap import mlab as matlab

>>> a = [[1, 2], [3, 4]]
>>> cell = matlab.mat2cell(array(a), [1, 1], [2])
>>> matlab.display(cell)

PROXY_VAL2__ = 

    [1x2 double]
    [1x2 double]

请注意,这个方法只适用于大小一致的列表。也就是说,像[[1,2],[3,4]]这样的可以用,但像[[1,2],[3,4,5]]就不行。这是因为mlabwrap对dtype=object类型的数组处理得不好,它更需要dtype=float类型的数组。

接下来我们快速切换到matlab做个对比:

>> display(cell)

cell = 

    [1x2 double]    [1x2 double]

看起来不错!不过,当我们切换回python,尝试访问我们创建的单元数组时:

>>> cell[0][0]

error: Unable to get matrix from MATLAB(TM) workspace

>>> cell[0, 0]

error: Unsupported index type: <type 'tuple'>

>>> type(cell)
mlabwrap.MlabObjectProxy

很遗憾,mlabwrap并不允许直接访问存储在MlabObjectProxy对象中的数据。有几种方法可以尝试解决这个问题。你可以在matlab中写一些cell_insertcell_pop函数。这些函数可以让你把python变量放入现有的单元数组中,并从单元数组中取出python可读的变量。或者,你也可以把单元数组写入一个.mat文件,然后用scipy.io.loadmat()在python中读取它。

老实说,除非你真的需要单元数组,否则我建议尽量避免通过mlabwrap使用它们。

撰写回答