如何从MATLAB向Python传递大型数组以避免内存重复拷贝?
避免MATLAB与Python间大型数组拷贝的方案
方法1:利用MATLAB Engine for Python的零拷贝转换
如果通过MATLAB Engine调用Python,不要用np.array()转换MATLAB数组,改用np.asarray()。只要MATLAB数组的内存布局(连续存储、数据类型匹配)与numpy兼容,np.asarray()会直接包装MATLAB的内存缓冲区,不会产生拷贝。
示例代码:
% MATLAB端:定义类并创建实例 classdef DataContainer properties largeArray double end methods function obj = DataContainer() obj.largeArray = rand(10000, 10000); % 大型数组 end end end % 启动Python引擎 pe = pyenv; if ~pe.IsLoaded pe = pyenv('Version','your_python_path'); end dataObj = DataContainer();
# Python端:通过Engine获取数组并零拷贝转换 import matlab.engine import numpy as np eng = matlab.engine.start_matlab() data_obj = eng.workspace['dataObj'] # 用asarray而非array,尝试共享内存 np_array = np.asarray(data_obj.largeArray)
注意:如果MATLAB数组是非连续存储(比如转置后的数组),asarray()还是会触发拷贝,此时可以在MATLAB端先调用dataObj.largeArray = dataObj.largeArray(:)强制转为连续存储。
方法2:内存映射文件(跨进程共享)
双方通过映射同一个磁盘文件实现内存共享,完全避免数据拷贝。
MATLAB端:写入内存映射文件
dataObj = DataContainer(); % 创建内存映射文件 filePath = 'large_array.dat'; m = memmapfile(filePath, 'Format', {'double', [size(dataObj.largeArray,1), size(dataObj.largeArray,2)], 'largeArray'}); m.Data.largeArray = dataObj.largeArray; clear m; % 释放映射,确保数据写入磁盘
Python端:映射同一个文件
import numpy as np filePath = 'large_array.dat' # 计算数组形状和字节数 shape = (10000, 10000) dtype = np.float64 byte_count = np.prod(shape) * dtype.itemsize # 映射文件到numpy数组 mmap_array = np.memmap(filePath, dtype=dtype, mode='r', shape=shape)
这种方法完全不涉及内存拷贝,适合超大型数组,但需要注意磁盘IO开销(首次写入文件时),以及确保两端的形状、数据类型完全一致。
方法3:利用MATLAB的C API传递指针(进阶)
如果对底层操作熟悉,可以用MATLAB的C API获取数组的内存指针,再在Python中用numpy.frombuffer()包装该指针。不过这种方法需要编写C扩展,复杂度较高,适合性能要求极端的场景。
核心思路:
- 在MATLAB中用
lib.pointer获取数组的内存地址。 - 在Python中用
ctypes接收指针,再用np.frombuffer()创建numpy数组(不拷贝)。
示例简化代码:
% MATLAB端获取指针 ptr = lib.pointer(dataObj.largeArray); addr = uint64(ptr); % 获取内存地址数值
# Python端包装指针 import numpy as np import ctypes addr = eng.workspace['addr'] shape = (10000, 10000) dtype = np.float64 # 用ctypes获取内存缓冲区 buf = ctypes.cast(addr, ctypes.POINTER(ctypes.c_double)) # 创建numpy数组,不拷贝 np_array = np.ctypeslib.as_array(buf, shape=shape)
注意:这种方法需要确保MATLAB数组在Python使用期间不会被释放,否则会导致内存访问错误;同时要保证两端的内存字节序一致。
内容的提问来源于stack exchange,提问作者Leon Williams
相关产品推荐
相关产品推荐

