LoginSignup
18
12

More than 5 years have passed since last update.

PythonでEDFファイルを読み込む方法

Posted at

ほとんど需要がないと思いますが、pyedflibの使い方の説明です。
最新情報は公式や公式のgithubをご覧ください。
http://pyedflib.readthedocs.io/en/latest/
https://github.com/holgern/pyedflib

EDFファイルとは?

EDF(European Data Format)は,医療データ(脳波など)の保存に使われるデータの保存形式です。
サンプルファイルはpyedflib公式のgithubレポジトリにあります。
https://github.com/holgern/pyedflib/tree/master/pyedflib/tests/data
もう少し実用的なデータのサンプルは,睡眠時脳波(PSG)なら以下のアドレスで配布されています。
https://www.physionet.org/pn4/sleep-edfx/
ダウンロードは自己責任で。

インストール

pipからインストールできます。
pip install pyedflib

使い方

pyedflibはEdfReaderとEdfWriterの2つに分かれています。
ここではEdfReaderについて説明します。(Writerは気が向けば・・・)

まずはファイルの読み込み

EDFの読み込み
path = "path_to_your_edf_file"

edf = pyedflib.EdfReader(path)

EDFファイルは,生体信号・サンプリング周波数・被験者情報・センサ情報など,様々なデータを格納しているため,データを取得するメソッドもたくさんあります。

メソッド一覧
EdfReader
- getNSamples(self)
  - データ点数を返します。
   [100 200 100 100]のように各チャンネル毎の値が出力されます。
- readAnnotations(self)
- getHeader(self)
 - 被験者情報や機器情報を返します。多分あまり使いません。
- getSignalHeader(self, chn)
 - 引数で指定したチャンネルの情報(センサ名・サンプリング周波数など)を返します。
- getSignalHeaders(self)
 - 上の関数を全チャンネル同時に。
- getTechnician(self)
- getRecordingAdditional(self)
- getPatientName(self)
- getPatientCode(self)
- getPatientAdditional(self)
- getEquipment(self)
- getAdmincode(self)
- getGender(self)
- getFileDuration(self)
 - 計測時間を返します。単位は秒です。
- getStartdatetime(self)
- getBirthdate(self, string=True)
- getSampleFrequencies(self)
- getSampleFrequency(self,chn)
- getSignalLabels(self)
 - センサ名が全てのチャンネル分返ってきます。
- getLabel(self,chn)
 - 指定したチャンネルのセンサ名が返ってきます。
- getPrefilter(self,chn)
 - 指定したチャンネルの前処理に使用したフィルタ情報を返します。
- getPhysicalMaximum(self,chn=None)
- getPhysicalMinimum(self,chn=None)
- getDigitalMaximum(self, chn=None)
- getDigitalMinimum(self, chn=None)
- getTransducer(self, chn)
 - 指定したチャンネルの計測機器の種類を返します。
- getPhysicalDimension(self, chn)
 - 指定したチャンネルの計測データの単位を返します。uV, mAなど。
- readSignal(self, chn, start=0, n=None)
 - 指定したチャンネルの計測データを返します。一番使います。
- file_info(self)
- file_info_long(self)

実行例

ここでは,PhysioNetからダウンロードした睡眠時PSGで実行例を示します。

import numpy as np
import pyedflib
import matplotlib.pyplot as plt

ファイルを読み込みます

edf = pyedflib.EdfReader("SC/SC4001E0-PSG.edf")

ラベルを出力してみます。

labels = edf.getSignalLabels()
print(labels)

['EEG Fpz-Cz', 'EEG Pz-Oz', 'EOG horizontal', 'Resp oro-nasal', 'EMG submental', 'Temp rectal', 'Event marker']

「EEG Fpz-Cz」「EEG Pz-Oz」など,7個のデータが入っていることが分かります。
続いて,計測時間・計測のサンプリング周波数・データ点数・計測日を表示します。

print("Duaration:"+str(edf.getFileDuration()))
print("Freq.:"+str(edf.getSampleFrequencies()))
print("N-Sample(=Freq x Duaration):"+str(edf.getNSamples()))
print("Date:"+str(edf.getStartdatetime()))

Duaration:79500
Freq.:[100 100 100 1 1 1 1]
N-Sample(=Freq x Duaration):[7950000 7950000 7950000 79500 79500 79500 79500]
Date:1989-04-24 16:13:00

信号を描画します。
ラベルのEEG-Fpz-Czなどは脳波計のセンサの装着位置の名前です。

plt.plot(edf.readSignal(0)[0:1000],label=labels[0])
plt.plot(edf.readSignal(1)[0:1000],label=labels[1])
plt.plot(edf.readSignal(2)[0:1000],label=labels[2])
plt.legend()
plt.show()

output_4_0.png

きちんと信号が取れていますね。
続いて,信号以外の情報について表示します。

print("Anotation:"+str(edf.read_annotation()))
print("Technician:"+str(edf.getTechnician()))
print("Header:"+str(edf.getHeader()))

Anotation:[]
Technician:
Header:{'technician': '', 'recording_additional': '', 'patientname': '', 'patient_additional': '', 'patientcode': '', 'equipment': '', 'admincode': '', 'gender': '', 'startdate': datetime.datetime(1989, 4, 24, 16, 13), 'birthdate': ''}

フリーで公開しているデータなので,情報は入っていませんね。
計測機器の情報はどうでしょうか?CH0のセンサについて表示します。

print("SIgnal-Header(CH-0):"+str(edf.getSignalHeader(0))+"¥n")

SIgnal-Header(CH-0):{'label': 'EEG Fpz-Cz', 'dimension': 'uV', 'sample_rate': 100, 'physical_max': 192.0, 'physical_min': -192.0, 'digital_max': 2047, 'digital_min': -2048, 'prefilter': 'HP:0.5Hz LP:100Hz [enhanced cassette BW]', 'transducer': 'Ag-AgCl electrodes'}

センサ「EEG Fpz-Cz」は単位はuVでサンプリング周波数が100で・・・と様々な情報が表示されています。
最後にファイルについての情報を表示すると,

print(edf.file_info())

file name: SC/SC4001E0-PSG.edf
signals in file: 7

終わりに

ドキュメントがほとんどない状態でgithubなどを見ながら気合いで書いたので,不正確な情報が含まれているかもしれません。
その場合はご連絡ください。

18
12
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
12