Python에서 MATLAB 데이터를 분류한 후 플로팅하기
이 예제에서는 환자에 대한 데이터를 Python®에서 흡연자와 비흡연자 목록으로 분류하고 MATLAB®을 사용하여 환자의 혈압 측정값을 플로팅하는 방법을 보여줍니다.
엔진을 시작하고, 환자 집합에 대한 데이터를 MATLAB 테이블로 읽어 들입니다. MATLAB은 100명의 환자에 대한 정보가 쉼표로 구분되어 들어 있는 샘플 파일 patients.dat
를 제공합니다.
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}
S
를 MATLAB 작업 공간에서 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 리스트 컴프리헨션(list comprehension)은 시퀀스를 대상으로 반복 작업을 수행할 수 있는 간결한 방법을 제공합니다. 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]
list
에서 흡연자의 혈압 측정값인 sp
의 길이를 표시합니다.
print(len(sp))
34
비흡연자의 측정값 list
인 nsp
의 길이를 표시합니다.
print(len(nsp))
66
흡연자 및 비흡연자의 평균 혈압 측정값을 계산합니다. sp
와 nsp
를 MATLAB mean
함수로 전달하기 전에 MATLAB 배열로 변환합니다.
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)
figure
, hold
및 box
함수는 출력 인수를 반환하지 않기 때문에 nargout=0
과 함께 호출해야 합니다.
흡연자 및 비흡연자의 혈압 측정값을 플로팅하고 플롯에 레이블을 지정합니다. 많은 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")