Interval-related Analysis#
This example can be referenced by citing the package.
This example shows how to use NeuroKit to analyze longer periods of data (i.e., greater than 10 seconds) such as resting state data. If you are looking to perform event-related analysis on epochs, you can refer to this NeuroKit example here.
# Load NeuroKit and other useful packages
import neurokit2 as nk
import pandas as pd
The Dataset#
First, download the dataset located on the GitHub repository.
It contains 5 minutes of physiological signals recorded at a frequency of 100Hz (5 x 60 x 100 = 30000 data points).
It contains the following signals : ECG, PPG, RSP
# Get data
data = nk.data("bio_resting_5min_100hz")
This is the resting state data from 1 participant who was asked to close his/her eyes for 8 minutes, trying not to think of anything as well as not to fall asleep.
Process the Signals#
In this analysis here, we will focus on extracting ECG and RSP features. To process the respective physiological signals, you can use ecg_process() and rsp_process(). You can then then visualize these signals using ecg_plot() and rsp_plot(). For the purposes of these example, we will select just 3000 datapoints (or 30s) to visualize.
Note: Do remember to specify the correct sampling_rate
(in this case, to 100Hz) in which the signals were generated, in all the relevant functions.
# Process ecg
ecg_signals, info = nk.ecg_process(data["ECG"], sampling_rate=100)
nk.ecg_plot(ecg_signals[:3000], info)
# Process rsp
rsp_signals, info = nk.rsp_process(data["RSP"], sampling_rate=100)
nk.rsp_plot(rsp_signals[:3000], info)
Extract Features#
Now that we have the processed signals, we can now perform the analysis using ecg_intervalrelated() and rsp_intervalrelated(). Simply provide the processed dataframe and these functions will return a dataframe of the features pertaining to the specific signal.
These features will be quite different from event-related features (See Event-related analysis example) as these signals were generated over a longer period of time. Hence, apart from the mean signal rate, variability metrices pertaining to heart rate variability (HRV) and respiratory rate variability (RRV) are also extracted here.
nk.ecg_intervalrelated(ecg_signals)
ECG_Rate_Mean | HRV_MeanNN | HRV_SDNN | HRV_SDANN1 | HRV_SDNNI1 | HRV_SDANN2 | HRV_SDNNI2 | HRV_SDANN5 | HRV_SDNNI5 | HRV_RMSSD | ... | HRV_SampEn | HRV_ShanEn | HRV_FuzzyEn | HRV_MSEn | HRV_CMSEn | HRV_RCMSEn | HRV_CD | HRV_HFD | HRV_KFD | HRV_LZC | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 86.392105 | [[69.47563805104409]] | [[4.903604322104105]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[3.8837766323814966]] | ... | [[1.9786368425578704]] | [[4.256941017033136]] | [[1.2686943754499123]] | [[1.404137826745609]] | [[1.469801247099329]] | [[2.572679544052144]] | [[1.562676080749381]] | [[1.8465069301766717]] | [[2.7223482404936066]] | [[0.8731238852455482]] |
1 rows × 92 columns
nk.rsp_intervalrelated(rsp_signals)
RSP_Rate_Mean | RRV_RMSSD | RRV_MeanBB | RRV_SDBB | RRV_SDSD | RRV_CVBB | RRV_CVSD | RRV_MedianBB | RRV_MadBB | RRV_MCVBB | ... | RAV_Mean | RAV_SD | RAV_RMSSD | RAV_CVSD | RSP_RVT | RSP_Symmetry_PeakTrough | RSP_Symmetry_RiseDecay | RSP_Phase_Duration_Inspiration | RSP_Phase_Duration_Expiration | RSP_Phase_Duration_Ratio | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 15.860331 | 134.651105 | 384.039474 | 102.06409 | 135.551343 | 0.265765 | 0.350618 | 360.5 | 51.1497 | 0.141885 | ... | 0.386252 | 0.201938 | 0.240509 | 0.622674 | 0.093298 | 0.617104 | 0.3989 | 0.152429 | 0.229395 | 0.664482 |
1 rows × 40 columns
Optional: Segmenting the Data#
If you want to segment your data for analysis, such as analyzing two separate portions of your resting state data, you can simply do so by splitting the ecg_signals
dataframe into epochs using epochs_create(). Using this example dataset, let’s say you want to analyze the first half and the second half of the ECG data. This means that each halved data would last for 60 x 2.5s = 150s.
In this function, we would also specify the onset of events to be at the 0th (for the first half of the data) and the 15000th datapoint (for the second half of the data), since there are 30000 data points in total.
# Half the data
epochs = nk.epochs_create(ecg_signals,
events=[0, 15000],
sampling_rate=100,
epochs_start=0,
epochs_end=150)
This returns a dictionary of 2 processed ECG dataframes, which you can then enter into ecg_intervalrelated()
.
# Analyze
nk.ecg_intervalrelated(epochs)
Label | ECG_Rate_Mean | HRV_MeanNN | HRV_SDNN | HRV_SDANN1 | HRV_SDNNI1 | HRV_SDANN2 | HRV_SDNNI2 | HRV_SDANN5 | HRV_SDNNI5 | ... | HRV_SampEn | HRV_ShanEn | HRV_FuzzyEn | HRV_MSEn | HRV_CMSEn | HRV_RCMSEn | HRV_CD | HRV_HFD | HRV_KFD | HRV_LZC | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 86.389814 | [[69.49767441860465]] | [[5.167181138835641]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | ... | [[1.2527629684953678]] | [[4.290505175709077]] | [[1.1667625041387146]] | [[1.3234302834078784]] | [[1.3340298186240032]] | [[1.5730504365078102]] | [[1.6535777692661096]] | [[1.8035044265520663]] | [[2.336829556302458]] | [[0.8288764443746864]] |
2 | 2 | 86.394396 | [[69.46046511627907]] | [[4.648089725942579]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | [[nan]] | ... | [[1.8817856208857746]] | [[4.080221616903997]] | [[1.3473463161429124]] | [[1.7371494891482802]] | [[1.4976794053994398]] | [[1.9578060920316949]] | [[1.5369379755191364]] | [[1.8952794259141006]] | [[3.094110204759245]] | [[0.9730288694833277]] |
2 rows × 93 columns
This then returns a dataframe of the analyzed features, with the rows representing the respective segmented signals. Try doing this with your own signals!