Python &引用;转换;Numpy阵列到Matlab,反之亦然
我正在寻找一种将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,
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
属性,而是一次迭代一项,而不是使用pythonmemoryview
协议:(。因此,这种方法的速度增益是微乎其微的。假设您有一个具有形状的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)