Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python &引用;转换;Numpy阵列到Matlab,反之亦然_Python_Matlab_Numpy - Fatal编程技术网

Python &引用;转换;Numpy阵列到Matlab,反之亦然

Python &引用;转换;Numpy阵列到Matlab,反之亦然,python,matlab,numpy,Python,Matlab,Numpy,我正在寻找一种将NumPy数组传递给Matlab的方法 我通过使用scipy.misc.imsave将数组存储到一个图像中,然后使用imread加载数组来实现这一点,但这当然会导致矩阵包含0到256之间的值,而不是“实”值 将这个矩阵的乘积除以256,原始NumPy数组中的最大值得到正确的矩阵,但我觉得这有点乏味 有更简单的方法吗?当然,只要使用scipy.io.savemat 例如: import numpy as np import scipy.io x = np.linspace(0,

我正在寻找一种将NumPy数组传递给Matlab的方法

我通过使用
scipy.misc.imsave
将数组存储到一个图像中,然后使用
imread
加载数组来实现这一点,但这当然会导致矩阵包含0到256之间的值,而不是“实”值

将这个矩阵的乘积除以256,原始NumPy数组中的最大值得到正确的矩阵,但我觉得这有点乏味


有更简单的方法吗?

当然,只要使用
scipy.io.savemat

例如:

import numpy as np
import scipy.io

x = np.linspace(0, 2 * np.pi, 100)
y = np.cos(x)

scipy.io.savemat('test.mat', dict(x=x, y=y))
类似地,还有
scipy.io.loadmat

然后,使用
负载测试
将其加载到matlab中


或者,正如@JAB所建议的,您可以将内容保存到ascii制表符分隔的文件中(例如
numpy.savetxt
)。然而,如果你走这条路线,你将被限制在2维之内。另一方面,ascii是通用的交换格式。几乎任何东西都可以处理带分隔符的文本文件。

不久前,我遇到了同样的问题,并编写了以下脚本,以方便从交互式会话中来回复制和粘贴数组。显然,这只适用于小型阵列,但我发现它比每次通过文件保存/加载更方便:


scipy.io.savemat或scipy.io.loadmat不适用于matlab数组——v7.3。但好的方面是matlab--v7.3文件是hdf5数据集。因此,可以使用多种工具读取它们,包括numpy

对于python,您将需要扩展,它需要在您的系统上安装

import numpy as np, h5py 
f = h5py.File('somefile.mat','r') 
data = f.get('data/variable1') 
data = np.array(data) # For converting to numpy array

一个简单的解决方案,无需通过文件或外部LIB传递数据。

Numpy有一种将ndarrays转换为列表的方法,可以从列表中定义matlab数据类型。那么,什么时候可以像这样变换:

np_a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
mat_a = matlab.double(np_a.tolist())
从matlab到python需要更多的关注。没有内置函数将类型直接转换为列表。但是我们可以访问原始数据,这些数据不是成形的,而是简单的。因此,我们使用
重塑
(正确格式化)和
转置
(因为MATLAB和numpy存储数据的方式不同)强调这一点非常重要:在项目中进行测试,主要是当您使用的矩阵超过2维时。它适用于MATLAB 2015a和2维

np_a = np.array(mat_a._data.tolist())
np_a = np_a.reshape(mat_a.size).transpose()
不确定它是否算作“更简单”,但我找到了一个解决方案,可以从python脚本中移动数据,该脚本由matlab快速调用:

dump_reader.py(python源代码):

dump_read.m(matlab脚本):

这取决于这样一个事实,即matlabs double与单元/矩阵相比,似乎在阵列上工作效率更高。第二个技巧是以有效的方式(通过pythons native array.array)将数据传递给matlabs double

顺便说一句,很抱歉发布了这个帖子,但我在这方面做了很多努力,这个话题是最热门的话题之一。也许这有助于缩短挣扎的时间


p.p.S.使用Matlab R2016b+python 3.5.4(64位)进行了测试。

这里有一个解决方案,可以避免在python中迭代,或使用文件IO,但代价是依赖(丑陋的)Matlab内部构件:

import matlab
# This is actually `matlab._internal`, but matlab/__init__.py
# mangles the path making it appear as `_internal`.
# Importing it under a different name would be a bad idea.
from _internal.mlarray_utils import _get_strides, _get_mlsize

def _wrapper__init__(self, arr):
    assert arr.dtype == type(self)._numpy_type
    self._python_type = type(arr.dtype.type().item())
    self._is_complex = np.issubdtype(arr.dtype, np.complexfloating)
    self._size = _get_mlsize(arr.shape)
    self._strides = _get_strides(self._size)[:-1]
    self._start = 0

    if self._is_complex:
        self._real = arr.real.ravel(order='F')
        self._imag = arr.imag.ravel(order='F')
    else:
        self._data = arr.ravel(order='F')

_wrappers = {}
def _define_wrapper(matlab_type, numpy_type):
    t = type(matlab_type.__name__, (matlab_type,), dict(
        __init__=_wrapper__init__,
        _numpy_type=numpy_type
    ))
    # this tricks matlab into accepting our new type
    t.__module__ = matlab_type.__module__
    _wrappers[numpy_type] = t

_define_wrapper(matlab.double, np.double)
_define_wrapper(matlab.single, np.single)
_define_wrapper(matlab.uint8, np.uint8)
_define_wrapper(matlab.int8, np.int8)
_define_wrapper(matlab.uint16, np.uint16)
_define_wrapper(matlab.int16, np.int16)
_define_wrapper(matlab.uint32, np.uint32)
_define_wrapper(matlab.int32, np.int32)
_define_wrapper(matlab.uint64, np.uint64)
_define_wrapper(matlab.int64, np.int64)
_define_wrapper(matlab.logical, np.bool_)

def as_matlab(arr):
    try:
        cls = _wrappers[arr.dtype.type]
    except KeyError:
        raise TypeError("Unsupported data type")
    return cls(arr)
到达这里所需的观察结果如下:

  • Matlab似乎只查看
    类型(x)。\uuuuu名称\uuuuuuu
    类型(x)。\uuuuuu模块\uuuuuuuuu
    来确定它是否理解类型
  • 似乎可以将任何可索引对象放置在
    \u data
    属性中

不幸的是,matlab没有在内部有效地使用
\u data
属性,而是一次迭代一项,而不是使用python
memoryview
协议:(。因此,这种方法的速度增益是微乎其微的。

假设您有一个具有形状的2D每日数据(365,10)在np数组
np3darat
中保存五年,该数组将有一个形状(5365,10)。在python中保存您的np数组:

import scipy.io as sio     #SciPy module to load and save mat-files
m['np3Darray']=np3Darray   #shape(5,365,10)
sio.savemat('file.mat',m)  #Save np 3D array 
然后在MATLAB中将np 3D数组转换为MATLAB 3D matix:

load('file.mat','np3Darray')
M3D=permute(np3Darray, [2 3 1]);   %Convert numpy array with shape (5,365,10) to MATLAB matrix with shape (365,10,5)

我忘了,Matlab允许解析文本文件吗?因为你可以把字符串中的NUMPY数组格式化为Matlab风格的字符串,把它们写到一个文件中,然后把数组读入Matlab。你是否考虑过mLabPress,你确定你不能在NUMPY/SCIPY中完全计算吗?我想我很确定我能够转换MMA。tlab将PLSM算法实现为numpy,但要解决由“一个接一个”和函数差异引起的所有问题非常耗时。感谢tip@JAB,这比先将其转换为图像要简单。不过,我可能会在以后遇到3D矩阵,所以Joe的解决方案对我来说是可行的。MATLAB可以读写HDF5格式,并且有python库…所以这允许将numpy数组保存到一个文件中,然后让matlab使用类似于加载('test.mat')?将使用
data.npz
data.npy
将不工作?如果不工作,为什么不工作?请注意
mat\u a=matlab.double(np\u a.tolist())
的效率可能非常低/速度非常慢。对于np数组以外的任何东西,都可以使用Joe Kington的答案。看,速度应该是非常显著的。我用这种方法得到了大约15倍。@max9111:你发现使用
数组.array
(就像你在那里做的那样)包装与不这样做(就像我在这里做的那样)相比有什么不同吗有什么不同吗?是的,你的版本更快;)。也许最好澄清一下,您的解决方案实际上比matlab.double(np_a.tolist())快得多。对于希望避免文件系统上的数据重复和任何与I/O相关的时间的情况,这似乎是最好的选择。对于100 x 100 x 100阵列,此方法每循环需要2.73 ms±191µs(平均值±标准偏差为7次运行,每个循环100次),但matlab.double每次运行1.12 s±58.1 ms(平均值±标准偏差为7次运行,每个循环1次)。大约400倍的加速。。。
import scipy.io as sio     #SciPy module to load and save mat-files
m['np3Darray']=np3Darray   #shape(5,365,10)
sio.savemat('file.mat',m)  #Save np 3D array 
load('file.mat','np3Darray')
M3D=permute(np3Darray, [2 3 1]);   %Convert numpy array with shape (5,365,10) to MATLAB matrix with shape (365,10,5)