使用Savitzky_Golay issu平滑Python曲线

2024-05-16 23:56:06 发布

您现在位置:Python中文网/ 问答频道 /正文

Input File CSV data link。我的Python代码粘贴在下面。曲线平滑技术似乎不起作用。当我在父数据上绘制平滑曲线时,它们完全重叠。有人能帮我解决这个问题吗。代码使用Savitzky_Golay算法代码从csv文件中提取xy轴数据,并进行公式化,以满足Savitzky_Golay函数调用所需的数据类型 enter image description here

    import numpy as np
    import csv
    from math import factorial
    import itertools
    import matplotlib.pyplot as plt
    from matplotlib.ticker import FormatStrFormatter
    #from scipy.interpolate import spline
    #import openpyxl
    #import pandas as pd
    #from scipy.interpolate import interp1d


    def savitzky_golay(y, window_size, order, deriv=0, rate=1):
        r"""Smooth (and optionally differentiate) data with a Savitzky-Golay filter.
        The Savitzky-Golay filter removes high frequency noise from data.
        It has the advantage of preserving the original shape and
        features of the signal better than other types of filtering
        approaches, such as moving averages techniques.
        Parameters
        ----------
        y : array_like, shape (N,)
          the values of the time history of the signal.
        window_size : int
          the length of the window. Must be an odd integer number.
        order : int
          the order of the polynomial used in the filtering.
          Must be less then `window_size` - 1.
        deriv: int
          the order of the derivative to compute (default = 0 means only smoothing)
        Returns
        -------
        ys : ndarray, shape (N)
          the smoothed signal (or it's n-th derivative).
        Notes
        -----
        The Savitzky-Golay is a type of low-pass filter, particularly
        suited for smoothing noisy data. The main idea behind this
        approach is to make for each point a least-square fit with a
        polynomial of high order over a odd-sized window centered at
        the point.
        Examples
        --------
        t = np.linspace(-4, 4, 500)
        y = np.exp( -t**2 ) + np.random.normal(0, 0.05, t.shape)
        ysg = savitzky_golay(y, window_size=31, order=4)
        import matplotlib.pyplot as plt
        plt.plot(t, y, label='Noisy signal')
        plt.plot(t, np.exp(-t**2), 'k', lw=1.5, label='Original signal')
        plt.plot(t, ysg, 'r', label='Filtered signal')
        plt.legend()
        plt.show()
        References
        ----------
        .. [1] A. Savitzky, M. J. E. Golay, Smoothing and Differentiation of
         Data by Simplified Least Squares Procedures. Analytical
         Chemistry, 1964, 36 (8), pp 1627-1639.
        .. [2] Numerical Recipes 3rd Edition: The Art of Scientific Computing
         W.H. Press, S.A. Teukolsky, W.T. Vetterling, B.P. Flannery
         Cambridge University Press ISBN-13: 9780521880688
        """

        try:
          window_size = np.abs(np.int(window_size))
          order = np.abs(np.int(order))
        except ValueError, msg:
          raise ValueError("window_size and order have to be of type int")
        if window_size % 2 != 1 or window_size < 1:
          raise TypeError("window_size size must be a positive odd number")
        if window_size < order + 2:
          raise TypeError("window_size is too small for the polynomials order")
        order_range = range(order+1)
        half_window = (window_size -1) // 2
        # precompute coefficients
        b = np.mat([[k**i for i in order_range] for k in range(-half_window, half_window+1)])
        m = np.linalg.pinv(b).A[deriv] * rate**deriv * factorial(deriv)
        # pad the signal at the extremes with
        # values taken from the signal itself
        firstvals = y[0] - np.abs( y[1:half_window+1][::-1] - y[0] )
        lastvals = y[-1] + np.abs(y[-half_window-1:-1][::-1] - y[-1])
        y = np.concatenate((firstvals, y, lastvals))
        return np.convolve( m[::-1], y, mode='valid')


    CurveName_1 = "Actual"
    ind1, ind2 = 0,0
    check = 0
    for line in open('C:\Users\XYZ\Documents\FileTransfers\Vicky.csv'):
        csv_row = line.split(",")
        csv_row = map(str.strip, csv_row)
        csv_row = [i.replace('"', '') for i in csv_row]
        if CurveName_1 in csv_row:
            ind1 = csv_row.index(CurveName_1)
            check += 1
        if check > 1:
            break

    x = []
    y = []
    with open( 'C:\Users\XYZ\Documents\FileTransfers\Vicky.csv', "r") as file:
        reader = csv.reader(file)
        for idx,line in enumerate(reader):
            if idx>3:
                x.append(float(line[ind1]))
                y.append(float(line[0]))
                #t=line[ind1],line[ind2]
                #print t

    print len(x)
    print len(y)

    xm = np.array(x)
    ym = np.array(y)

    #ym = np.array(ym)
    yhat = savitzky_golay(ym, 51, 3) # window size 51, polynomial order 3

    plt.grid(True)
    plt.minorticks_on()
    # Customize the major grid
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='red')
    # Customize the minor grid
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    axes = plt.subplot(111)
    axes.xaxis.set_minor_formatter(FormatStrFormatter("%.2f"))
    axes.yaxis.set_minor_formatter(FormatStrFormatter("%.2f"))
    plt.plot(yhat, xm)
    plt.plot(ym,xm, color='red')
    plt.show()

Tags: ofcsvtheinimportforsizesignal