Main Content

PythonMATLAB 数据进行分类并绘图

此示例说明如何在 Python® 中将患者数据分类到吸烟者和非吸烟者列表中,并对 MATLAB® 患者的血压读数绘图。

启动引擎,将一组患者的数据读入 MATLAB 表。MATLAB 提供以逗号分隔的示例文件 patients.dat,其中包含 100 名不同患者的信息。

import matlab.engine
eng = matlab.engine.start_matlab()
eng.eval("T = readtable('patients.dat');",nargout=0)

MATLAB readtable 函数将数据读入表中。引擎不支持 MATLAB 表数据类型。不过,使用 MATLAB table2struct 函数,您可以将表转换为标量结构体,这是引擎支持的数据类型。

eng.eval("S = table2struct(T,'ToScalar',true);",nargout=0)
eng.eval("disp(S)",nargout=0)
                    LastName: {100x1 cell}
                      Gender: {100x1 cell}
                         Age: [100x1 double]
                    Location: {100x1 cell}
                      Height: [100x1 double]
                      Weight: [100x1 double]
                      Smoker: [100x1 double]
                    Systolic: [100x1 double]
                   Diastolic: [100x1 double]
    SelfAssessedHealthStatus: {100x1 cell}

您可以将 MATLAB 工作区中的 S 传递给您的 Python 会话。引擎将 S 转换为 Python 字典 D

D = eng.workspace["S"]

S 的字段包含数组。该引擎将元胞数组转换为 Python list 变量,并将数值数组转换为 MATLAB 数组。因此,D["LastName"] 的数据类型为 list,而 D["Age"] 的数据类型为 matlab.double

将血压读数分为吸烟者和非吸烟者列表。在 patients.dat 中,Smoker 列用逻辑值 1 (true) 表示吸烟者,用逻辑值 0 (false) 表示非吸烟者。将 D["Smoker"] 转换为 matlab.logical 数组以进行分类。

smoker = matlab.logical(D["Smoker"])

Diastolic 血压读数和 Smoker 指示符转换为 1×100 MATLAB 数组以进行分类。

pressure = D["Diastolic"]
pressure.reshape((1,100))
pressure = pressure[0]
smoker.reshape((1,100))
smoker = smoker[0]

pressure 数组分为吸烟者和非吸烟者的血压读数列表。Python 列表推导式为迭代序列提供了一种紧凑的方法。使用 Python zip 函数,可以在单个 for 循环中迭代多个序列。

sp = [p for (p,s) in zip(pressure,smoker) if s is True]
nsp = [p for (p,s) in zip(pressure,smoker) if s is False]

显示吸烟者的血压读数 splist 类型)的长度。

print(len(sp))
34

显示非吸烟者读数 nsplist 类型)的长度。

print(len(nsp))
66

计算吸烟者和非吸烟者的平均血压读数。将 spnsp 转换为 MATLAB 数组,然后将它们传递给 MATLAB mean 函数。

sp = matlab.double(sp)
nsp = matlab.double(nsp)
print(eng.mean(sp))
89.9117647059

显示非吸烟者的均值血压。

print(eng.mean(nsp))
79.3787878788

绘制吸烟者和非吸烟者的血压读数。要为绘图定义两个 x 轴,请调用 MATLAB linspace 函数。您可以在同一个散点图上绘制 34 个吸烟者和 66 个非吸烟者。

sdx = eng.linspace(1.0,34.0,34)
nsdx = eng.linspace(1.0,34.0,66)

使用 box 函数显示轴边界。

eng.figure(nargout=0)
eng.hold("on",nargout=0)
eng.box("on",nargout=0)

您必须使用 nargout=0 调用 figureholdbox 函数,因为这些函数不返回输出参量。

绘制吸烟者和非吸烟者的血压读数,并对绘图加标签。对于许多 MATLAB 函数,引擎可以返回 MATLAB 图形对象的句柄。您可以将 MATLAB 对象的句柄存储在 Python 变量中,但无法操作 Python 中的对象属性。您可以将 MATLAB 对象作为输入参量传递给其他 MATLAB 函数。

eng.scatter(sdx,sp,10,'blue')
<matlab.object object at 0x22d1510>

在此示例的其余部分,将 MATLAB 函数的输出参量赋给占位符 h

h = eng.scatter(nsdx,nsp,10,'red')
h = eng.xlabel("Patient (Anonymized)")
h = eng.ylabel("Diastolic Blood Pressure (mm Hg)")
h = eng.title("Blood Pressure Readings for All Patients")
h = eng.legend("Smokers","Nonsmokers")

绘制吸烟者和非吸烟者的平均血压读数。

x = matlab.double([0,35])
y = matlab.double([89.9,89.9])
h = eng.line(x,y,"Color","blue")
h = eng.text(21.0,88.5,"89.9 (Smoker avg.)","Color","blue")
y = matlab.double([79.4,79.4])
h = eng.line(x,y,"Color","red")
h = eng.text(5.0,81.0,"79.4 (Nonsmoker avg.)","Color","red")

Plot of blood pressure readings for all patients.

另请参阅

|