Python中MNE庫進行PSD分析(計算不同頻率區間的累加和)

使用的代碼和數據:https://download.csdn.net/download/zhoudapeng01/12545345

在做腦波數據分析的時候,免不了需要進行頻率域的數據分析,功率譜密度是常用的一種分析方法,在MNE庫中有psd算法的實現。開始使用之前推薦個博客,https://zhuanlan.zhihu.com/p/49328001 講解了什麼是PSD。有一點需要注意,PSD通常根據頻率分辨率做歸一化也就是其分母爲採樣點數。

對應的官方實例:https://mne.tools/stable/auto_tutorials/time-freq/plot_sensors_time_frequency.html#sphx-glr-auto-tutorials-time-freq-plot-sensors-time-frequency-py

本文是以BCI競賽的數據爲例,文章中的數據和代碼如下:

https://download.csdn.net/download/zhoudapeng01/12545345

數據是挑選有效epoch後保存爲fif格式的,有關保存epoch格式的數據詳情見博客https://blog.csdn.net/zhoudapeng01/article/details/103893014

這種方法有一個問題就是隻有繪製的圖像,不能針對相關的數據進行後續處理。實際上mne中還有其他一些細節計算的方法,比如:mne.time_frequency.psd_welch(),mne.time_frequency.psd_multitaper() 等,其在官方的實例中均有體現。這裏以用psd_multitaper計算不同頻率區間的累加和爲例:主要的目的是計算不同事件在不同頻率區間的能量和,這裏只分析一個通道的結果

import mne
import numpy as np
import matplotlib.pyplot as plt
from mne.time_frequency import psd_multitaper

mne.set_log_level(False)
# 設置分析頻率的區間範圍,這裏有小數主要是爲了和後面小波變換方法做對比(暫時未實現)。
iter_freqs = [
    {'name': 'Delta', 'fmin': 0, 'fmax': 3.75},
    {'name': 'Theta', 'fmin': 3.75, 'fmax': 7.5},
    {'name': 'Alpha', 'fmin': 7.5, 'fmax': 12.5},
    {'name': 'Beta',  'fmin': 12.5, 'fmax': 35},
]
# 設置不同事件對應的顏色
color_events = {'cueLeft': (1, 0, 0), 'cueRight': (0, 1, 0), 'cueFoot': (0, 0, 1), 'cueTongue': (1, 1, 0)}

#################psd計算頻率區間的能量分佈(單通道)############
def EpochPSDEnergy(epochs):
    # 遍歷epochs中的不同事件
    for event in epochs.event_id:
        # 計算某個事件對應所有epochs的功率譜密度(返回爲ndarray)
        psds, freqs = psd_multitaper(epochs[event], n_jobs=1)
        # 計算事件對應epochs的均值
        psds = np.squeeze(np.average(psds, axis=0))
        #初始化能量矩陣
        eventEnergy =[]
        # 遍歷不同頻率區間的能量和
        for iter_freq in iter_freqs:
            eventEnergy.append(np.sum(psds[(iter_freq['fmin'] < freqs) & (freqs < iter_freq['fmax'])]))
        # 繪製不同事件、不同頻率區間的能量值
        plt.plot([xLabel['name'] for xLabel in iter_freqs], eventEnergy, color=color_events[event], label=event, marker='o', lw=0, ms=5)
    # 設置標題
    plt.title('PSD_SUM')
    # 設置圖例
    plt.legend()
    # 繪圖顯示
    plt.show()


if __name__ == '__main__':
    # 讀取篩選好的epoch數據
    epochs = mne.read_epochs(r'F:\BaiduNetdiskDownload\BCICompetition\BCICIV_2a_gdf\Train\Fif\A02T_epo.fif')
    # 這裏只分析一個通道的psd
    epochs.pick(['EEG-Cz']).plot_psd()
    # 繪製不同區間的能量分佈
    EpochPSDEnergy(epochs.pick(['EEG-Cz']))

只實現了算法,還沒具體分析有什麼規律。。。

PS:實際上Python中的matplotlib中是自帶psd計算方法的,如果不想用mne也可以直接調用matplotlib中的方法。

https://www.osgeo.cn/matplotlib/gallery/lines_bars_and_markers/psd_demo.html

https://www.osgeo.cn/matplotlib/api/_as_gen/matplotlib.pyplot.psd.html?highlight=psd#matplotlib.pyplot.psd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章