Source code for pysdkit.utils._smooth1d

# -*- coding: utf-8 -*-
"""
Created on 2024/6/3 15:31
@author: Whenxuan Wang
@email: wwhenxuan@gmail.com
"""
import numpy as np
from scipy.ndimage import gaussian_filter1d
from scipy.signal import savgol_filter


def simple_moving_average(signal: np.ndarray, window_size: int = 2) -> np.ndarray:
    """
    Simple Moving Average

    :param signal: Input signal (numpy array)
    :param window_size: Window size for averaging (default is 2)
    :return: Smoothed signal (numpy array)
    """
    return np.convolve(signal, np.ones(window_size) / window_size, mode="same")


def weighted_moving_average(signal: np.ndarray, window_size: int = 2) -> np.ndarray:
    """
    Weighted Moving Average

    :param signal: Input signal (numpy array)
    :param window_size: Window size for averaging (default is 2)
    :return: Smoothed signal (numpy array)
    """
    weights = np.arange(1, window_size + 1)
    return np.convolve(signal, weights / weights.sum(), mode="same")


[docs] def gaussian_smoothing(signal: np.ndarray, sigma: int = 2) -> np.ndarray: """ Gaussian Filtering Smoothing :param signal: Input signal (numpy array) :param sigma: Standard deviation for Gaussian kernel (default is 2) :return: Smoothed signal (numpy array) """ return gaussian_filter1d(signal, sigma=sigma)
[docs] def savgol_smoothing( signal: np.ndarray, window_length: int = 11, poly_order: int = 2 ) -> np.ndarray: """ Savitzky-Golay Filtering Smoothing :param signal: Input signal (numpy array) :param window_length: Length of the filter window (default is 11, must be odd) :param poly_order: Order of the polynomial used to fit the X (default is 2) :return: Smoothed signal (numpy array) """ assert window_length % 2 == 1, "the window length must be odd!" return savgol_filter(signal, window_length=window_length, polyorder=poly_order)
[docs] def exponential_smoothing(signal: np.ndarray, alpha: float = 0.4) -> np.ndarray: """ Exponential Smoothing (Single Exponential Smoothing) :param signal: Input signal (numpy array) :param alpha: Smoothing factor, range from 0 to 1 (default is 0.4) :return: Smoothed signal (numpy array) """ smoothed_signal = np.zeros_like(signal) # Initial smoothed value set to the first data point smoothed_signal[0] = signal[0] for t in range(1, len(signal)): smoothed_signal[t] = alpha * signal[t] + (1 - alpha) * smoothed_signal[t - 1] return smoothed_signal
def smooth_show_info(): """ Visualize different signal smoothing methods on a test signal """ import matplotlib.pyplot as plt # Generate test signal np.random.seed(0) x = np.linspace(0, 2 * np.pi, 100) signal = np.sin(x) + np.random.normal(0, 0.1, x.size) # Create figure and axis objects fig, ax = plt.subplots(figsize=(12, 5)) # Apply signal smoothing algorithms and visualize ax.plot(x, signal, label="Original Signal", alpha=0.8) ax.plot( x, simple_moving_average(signal=signal, window_size=5), label="Simple Moving Average", alpha=0.7, ) ax.plot( x, weighted_moving_average(signal=signal, window_size=5), label="Weighted Moving Average", alpha=0.7, ) ax.plot( x, gaussian_smoothing(signal=signal, sigma=3), label="Gaussian Filtering", alpha=0.7, ) ax.plot( x, savgol_smoothing(signal=signal), label="Savitzky-Golay Filtering", alpha=0.7 ) ax.plot( x, exponential_smoothing(signal=signal, alpha=0.4), label="Exponential Smoothing", alpha=0.7, ) # Add legend ax.legend(loc="best", fontsize=11) return fig