Source code for vitalDSP.utils.signal_processing.interpolations

"""
Utility Functions Module for Physiological Signal Processing

This module provides comprehensive capabilities for physiological
signal processing including ECG, PPG, EEG, and other vital signs.

Author: vitalDSP Team
Date: 2025-01-27
Version: 1.0.0

Key Features:
- Multiple processing methods and functions
- NumPy integration for numerical computations
- SciPy integration for advanced signal processing

Examples:
--------
Basic usage:
    >>> import numpy as np
    >>> from vitalDSP.signal_processing.interpolations import Interpolations
    >>> signal = np.random.randn(1000)
    >>> processor = Interpolations(signal)
    >>> result = processor.process()
    >>> print(f'Processing result: {result}')
"""

import numpy as np
import pandas as pd
from scipy.interpolate import UnivariateSpline


[docs] def linear_interpolation(intervals): """ Impute missing values using linear interpolation. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. Returns ------- np.array The array with missing values imputed using linear interpolation. Example ------- >>> linear_interpolation(np.array([0.8, np.nan, 0.82, np.nan, 0.85])) """ rr_series = pd.Series(intervals) # Use pandas interpolation with linear method return rr_series.interpolate(method="linear", limit_direction="both").to_numpy()
[docs] def spline_interpolation(intervals, order=3): """ Impute missing values using spline interpolation. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. order : int, optional The order of the spline, defaults to 3 (cubic spline). Returns ------- np.array The array with missing values imputed using spline interpolation. Example ------- >>> spline_interpolation(np.array([0.8, np.nan, 0.82, np.nan, 0.85]), order=3) """ # rr_series = pd.Series(intervals) index = np.arange(len(intervals)) valid = ~np.isnan(intervals) # Edge case: if not enough valid points for spline of given order, fall back to linear interpolation if valid.sum() < order + 1: return linear_interpolation(intervals) # Perform spline interpolation spline = UnivariateSpline(index[valid], intervals[valid], k=order, s=0) return spline(index)
[docs] def mean_imputation(intervals): """ Impute missing values by replacing them with the mean of the valid RR intervals. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. Returns ------- np.array The array with missing values imputed using the mean of valid intervals. Example ------- >>> mean_imputation(np.array([0.8, np.nan, 0.82, np.nan, 0.85])) """ # Avoid "mean of empty slice" warning if len(intervals) == 0 or np.all(np.isnan(intervals)): return intervals # Return as-is if no valid data mean_value = np.nanmean(intervals) return np.where(np.isnan(intervals), mean_value, intervals)
[docs] def median_imputation(intervals): """ Impute missing values by replacing them with the median of the valid RR intervals. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. Returns ------- np.array The array with missing values imputed using the median of valid intervals. Example ------- >>> median_imputation(np.array([0.8, np.nan, 0.82, np.nan, 0.85])) """ # Avoid "All-NaN slice encountered" warning if len(intervals) == 0 or np.all(np.isnan(intervals)): return intervals # Return as-is if no valid data median_value = np.nanmedian(intervals) return np.where(np.isnan(intervals), median_value, intervals)
[docs] def forward_fill(intervals): """ Impute missing values by carrying forward the last valid RR interval. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. Returns ------- np.array The array with missing values imputed using forward fill. Example ------- >>> forward_fill(np.array([0.8, np.nan, 0.82, np.nan, 0.85])) """ rr_series = pd.Series(intervals) return rr_series.ffill().bfill().to_numpy()
[docs] def backward_fill(intervals): """ Impute missing values by carrying backward the next valid RR interval. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. Returns ------- np.array The array with missing values imputed using backward fill. Example ------- >>> backward_fill(np.array([0.8, np.nan, 0.82, np.nan, 0.85])) """ rr_series = pd.Series(intervals) return rr_series.bfill().ffill().to_numpy()
[docs] def rolling_mean_imputation(intervals, window=5): """ Impute missing values using the rolling mean of valid RR intervals. Parameters ---------- intervals : np.array The array of RR intervals with NaN values. window : int, optional The window size for the rolling mean. Defaults to 5. Returns ------- np.array The array with missing values imputed using the rolling mean. Example ------- >>> rolling_mean_imputation(np.array([0.8, np.nan, 0.82, np.nan, 0.85]), window=3) """ rr_series = pd.Series(intervals) # Apply rolling mean with window size intervals_imputed = rr_series.fillna( rr_series.rolling(window, min_periods=1).mean() ) # Forward and backward fill for edge cases (start and end NaNs) intervals_imputed = intervals_imputed.ffill().bfill() return intervals_imputed.to_numpy()