1. MATLAB与Python环境互操作与数据交换

任务拆解:一条 CSV 数据从磁盘到 MATLAB 图窗的完整链路

本例要验证的不是“MATLAB 能不能调用 Python”,而是数据在两种语言之间往返时是否保持类型、形状和数值一致。整条链路包含四个关键交接点:MATLAB 向 Python 传递文件路径、Python 读取并计算、Python 结果转换为 MATLAB 可识别的类型、MATLAB 绘图验证。任何一个交接点出错,最终图形都会表现为空图、维度错误或数值异常。

MATLAB 工作区 csvPath = "sensor.csv" 字符串路径(char/string) py.analyze_csv(csvPath) 调用 Python 函数 result = double(pyOut) 类型转换:py.array → double plot(t, result) 绘图验证数值与形状 Python 解释器 def analyze_csv(path): 接收路径参数 np.loadtxt(path, ...) 读取 CSV → ndarray smooth = np.convolve(...) 滑动平均处理 return smooth 返回 ndarray 磁盘文件 sensor.csv t, value 0.0, 12.3 0.1, 12.8 ... MATLAB 图窗 平滑后曲线 路径字符串 读取 ndarray 返回 double 数组绘图 关键交接点:路径传递 → 文件读取 → 类型转换 → 绘图验证

环境准备与版本约束

MATLAB 从 R2014b 起支持 py. 接口,但不同版本对 Python 的支持范围不同。执行前先确认当前 MATLAB 绑定的 Python 版本,避免出现“找不到模块”或“解释器不兼容”的错误。

% 查看 MATLAB 当前使用的 Python 解释器
pyenv

% 若未配置,可指定 Python 路径(示例路径需按本机实际修改)
pyenv('Version', 'C:\Python311\python.exe');

% 验证基本调用
py.sys.version

Python 侧需要 numpy。若 MATLAB 绑定的解释器没有该包,可在系统命令行中执行 python -m pip install numpy,安装到同一个解释器环境。

Python 侧:编写可被 MATLAB 调用的分析脚本

MATLAB 调用 Python 时,函数必须位于 Python 的搜索路径上。最稳妥的做法是把脚本放在当前 MATLAB 工作目录,并在调用前把该目录加入 Python 路径。下面这个脚本读取两列 CSV(时间、数值),对数值列做 5 点滑动平均,返回平滑后的数组。

# analyze_csv.py
import numpy as np

def analyze_csv(path, window=5):
    """读取两列 CSV,对第二列做滑动平均,返回平滑结果。"""
    data = np.loadtxt(path, delimiter=",", skiprows=1)
    t = data[:, 0]
    v = data[:, 1]
    kernel = np.ones(window) / window
    smooth = np.convolve(v, kernel, mode="same")
    return smooth

注意 mode="same" 使输出长度与输入一致,这样 MATLAB 侧可以直接用同一组时间轴绘图,不需要额外对齐长度。

MATLAB 侧:调用、转换与绘图

核心操作分三步:把工作目录加入 Python 路径、调用函数、把返回的 py.numpy.ndarray 转成 MATLAB 的 double 列向量。转换时用 double() 包裹,并用 reshape 或转置保证方向一致。

% 1. 让 Python 能找到脚本
pyPath = fileparts(mfilename('fullpath'));
if isempty(pyPath), pyPath = pwd; end
insert(py.sys.path, int32(0), pyPath);

% 2. 准备数据文件(示例数据,首次运行时生成)
csvFile = fullfile(pyPath, 'sensor.csv');
if ~isfile(csvFile)
    t = (0:0.1:9.9)';
    v = 12 + 0.8*sin(t) + 0.3*randn(size(t));
    writematrix([t, v], csvFile);
end

% 3. 调用 Python 函数
pyOut = py.analyze_csv.analyze_csv(csvFile, int32(5));

% 4. 类型转换:py.ndarray → double 列向量
smooth = double(pyOut);
smooth = smooth(:);

% 5. 读取时间轴并绘图验证
raw = readmatrix(csvFile);
t = raw(:, 1);
figure;
plot(t, raw(:, 2), 'Color', [0.7 0.7 0.7], 'DisplayName', '原始数据');
hold on;
plot(t, smooth, 'b-', 'LineWidth', 1.5, 'DisplayName', 'Python 平滑结果');
xlabel('时间 t'); ylabel('数值');
legend('Location', 'best');
title('MATLAB 调用 Python 处理 CSV 并回传绘图');
若 py.analyze_csv.analyze_csv 报“module not found”,优先检查 insert(py.sys.path, ...) 是否执行成功,以及脚本文件名是否与模块名一致。MATLAB 的 Python 路径与系统命令行中的 sys.path 是两套独立配置。

结果判读与链路验证

运行后应看到两条曲线:灰色原始数据带有随机波动,蓝色平滑曲线明显更平缓,且两者在时间轴上完全重合。若蓝色曲线为空或长度不符,按以下顺序排查:

现象可能原因验证方法
调用报 module not found脚本目录未加入 Python 路径在 MATLAB 中执行 py.sys.path 查看是否包含工作目录
返回类型为 py.numpy.ndarray 无法直接绘图未做 double() 转换class(pyOut) 与 class(smooth) 对比
绘图维度不匹配返回行向量而时间轴为列向量用 size(smooth) 与 size(t) 检查,必要时 smooth(:)
曲线数值异常偏大或偏小CSV 分隔符或跳过行数设置错误用 readmatrix 读同一文件对比首行数值

可复用的验证脚本片段

把链路验证固化成一段可重复执行的检查代码,每次修改 Python 脚本后先跑它,比直接看图更快定位问题。

% 链路自检:类型、形状、数值范围
assert(isa(pyOut, 'py.numpy.ndarray'), '返回值不是 ndarray');
assert(numel(smooth) == size(raw, 1), '长度与原始数据不一致');
assert(all(isfinite(smooth)), '存在 NaN 或 Inf');
fprintf('链路正常:%d 个点,范围 [%.3f, %.3f]\n', ...
    numel(smooth), min(smooth), max(smooth));

这段自检覆盖了跨语言交换中最常见的三类失败:类型未转换、形状不一致、数值非法。通过后再绘图,可以把“图不对”的问题缩小到绘图参数本身,而不是数据链路。