Source code for tensorpac.stats

"""Statistics for cross frequency coupling."""
import logging

import numpy as np

from tensorpac.io import is_pandas_installed, is_statsmodels_installed

logger = logging.getLogger('tensorpac')


[docs]def test_stationarity(x, p=.05): """Test the stationarity of an electrophysiological dataset. This function performs a Augmented Dickey-Fuller test and returns a table (dataframe) with statistical properties for each epoch. Parameters ---------- x : array_like Array of data of shape (n_epochs, n_times) p : float | 0.05 P-value to use as a threshold in order to infer if the time-series are significantly stationary Returns ------- df : pandas.DataFrame Dataframe that contains the statistical properties for each epoch. The table contains the followong columns : * Epochs : epoch number * P-values * Stationary : boolean indicating if the time-serie is significantly stationary at the critical level p * Statistics : statistical test * CV (5%) and CV (1%) : critical value respectively at 5% and 1% Notes ----- This function requires both pandas and statsmodels Python packages. See : * Pandas : https://pandas.pydata.org/pandas-docs/stable/install.html * Statsmodels : http://www.statsmodels.org/stable/install.html """ is_pandas_installed() is_statsmodels_installed() import pandas as pd from statsmodels.tsa.stattools import adfuller x = np.atleast_2d(x) assert x.ndim == 2, ("x should be a two dimentional array of shape " "(n_epochs, n_times)") n_epochs, n_times = x.shape # test time series logger.info(f"Performing a Augmented Dickey-Fuller test on {n_epochs} " f"epochs with p={p}") epochs = ['epoch %i' % k for k in range(n_epochs)] pvalues = np.zeros((n_epochs,), dtype=float) adf_stat = np.zeros_like(pvalues) stationary = np.zeros_like(pvalues, dtype=bool) cv_5, cv_1 = np.zeros_like(pvalues), np.zeros_like(pvalues) for k in range(n_epochs): result = adfuller(x[k, :]) adf_stat[k], pvalues[k] = result[0], result[1] cv_5[k], cv_1[k] = result[4]['5%'], result[4]['1%'] stationary[k] = result[1] <= p # pandas formating cols = ['Epochs', 'P-values', f'Stationary', 'Statistics', 'CV (5%)', 'CV (1%)'] df = pd.DataFrame({cols[0]: epochs, cols[1]: pvalues, cols[2]: stationary, cols[3]: adf_stat, cols[4]: cv_5, cols[5]: cv_1}, columns=cols) n_signi = stationary.sum() # n_not_signi = (~stationary.sum()) logger.info(f" {n_signi}/{n_epochs} epochs were found as significantly " f"stationary at p={p}") return df