2

ほぼ毎秒繰り返されるプロセスの各サイクルで少し変化する繰り返し信号がありますが、各サイクルの期間と内容は、いくつかのパラメーター内で互いに少し異なります。私の信号データの1秒ごとに1000のx、y座標があります。各サイクル内のデータの小さいが重要なセグメントが破損しているため、破損した各セグメントを上向きの放物線に置き換えたいと思います。

放物線で置き換える必要のあるデータセグメントごとに、3点のx、y座標があります。頂点/最小値はそれらのポイントの1つです。そして、他の2つのポイントは、放物線である上向きのU字型の左右の上部です。つまり、左上はこの関数の定義域内の最小のx値のx、y座標ペアであり、右上はこの関数の定義域内の最大のx値のx、y座標ペアです。左上と右上のy座標は互いに等しく、データセグメントで最も高い2つのy値です。

この上向きの放物線に残りのデータポイントをプロットするコードをどのように記述できますか? この関数は、データの1分ごとに60回または70回呼び出す必要があり、放物線の形状/式は、これら3つのペア間の異なる関係を説明するために、この関数が呼び出されるたびに変更する必要があることに注意してください。結果として得られる各放物線のx、y座標。

def ReplaceCorruptedDataWithParabola(Xarray, Yarray, LeftTopX, LeftTopY
                                     , LeftTopIndex, MinX, MinY, MinIndex
                                     , RightTopX, RightTopY, RightTopIndex):  

    # Step One: Derive the formula for the upward-facing parabola using 
    # the following data from the three points:
        LeftTopX,LeftTopY,LeftTopIndex  
        MinX,MinY,MinIndex  
        RightTopX,RightTopY,RightTopIndex 

    # Step Two: Use the formula derived in step one to plot the parabola in
    # the places where the corrupted data used to reside:
    for n in Xarray[LeftTopX:RightTopX]:
        Yarray[n]=[_**The formula goes here**_]

    return Yarray 

注:XarrayとYarrayはそれぞれ単一列のベクトルであり、各インデックスにデータがあり、2つの配列をx、y座標のセットとしてリンクします。どちらもNumpy配列です。Xarrayには時間情報が含まれており、変更されませんが、Yarrayには、この関数で計算する必要のある放物線データに置き換えられる破損したセグメントを含む信号データが含まれています。

4

1 に答える 1

7

ですから、私が理解しているように、放物線を当てはめる3つのポイントがあります。

通常、numpy.polyfitを使用するのが最も簡単ですが、速度が本当に心配で、正確に3点を近似している場合は、最小二乗近似を使用しても意味がありません。

代わりに、均一に決定されたシステム(放物線を3 x、y点に当てはめる)があり、単純な線形代数で正確な解を得ることができます。

したがって、全体として、次のようなことを行う可能性があります(これのほとんどはデータのプロットです):

import numpy as np                                                                              
import matplotlib.pyplot as plt                                                                 

def main():
    # Generate some random data
    x = np.linspace(0, 10, 100)
    y = np.cumsum(np.random.random(100) - 0.5)

    # Just selecting these arbitrarly 
    left_idx, right_idx = 20, 50      
    # Using the mininum y-value within the arbitrary range
    min_idx = np.argmin(y[left_idx:right_idx]) + left_idx 

    # Replace the data within the range with a fitted parabola
    new_y = replace_data(x, y, left_idx, right_idx, min_idx)  

    # Plot the data
    fig = plt.figure()
    indicies = [left_idx, min_idx, right_idx]

    ax1 = fig.add_subplot(2, 1, 1)
    ax1.axvspan(x[left_idx], x[right_idx], facecolor='red', alpha=0.5)
    ax1.plot(x, y)                                                    
    ax1.plot(x[indicies], y[indicies], 'ro')                          

    ax2 = fig.add_subplot(2, 1, 2)
    ax2.axvspan(x[left_idx], x[right_idx], facecolor='red', alpha=0.5)
    ax2.plot(x,new_y)                                                 
    ax2.plot(x[indicies], y[indicies], 'ro')

    plt.show()

def fit_parabola(x, y):
    """Fits the equation "y = ax^2 + bx + c" given exactly 3 points as two
    lists or arrays of x & y coordinates"""
    A = np.zeros((3,3), dtype=np.float)
    A[:,0] = x**2
    A[:,1] = x
    A[:,2] = 1
    a, b, c = np.linalg.solve(A, y)
    return a, b, c

def replace_data(x, y, left_idx, right_idx, min_idx):
    """Replace the section of "y" between the indicies "left_idx" and
    "right_idx" with a parabola fitted to the three x,y points represented
    by "left_idx", "min_idx", and "right_idx"."""
    x_fit = x[[left_idx, min_idx, right_idx]]
    y_fit = y[[left_idx, min_idx, right_idx]]
    a, b, c = fit_parabola(x_fit, y_fit)

    new_x = x[left_idx:right_idx]
    new_y = a * new_x**2 + b * new_x + c

    y = y.copy() # Remove this if you want to modify y in-place
    y[left_idx:right_idx] = new_y
    return y

if __name__ == '__main__':
    main()

プロット例

それが少し役立つことを願っています...

于 2010-10-29T03:16:04.187 に答える