2015-03-19 7 views
9

Obecnie pracuję z niektórymi danymi z Spectra Ramana i próbuję poprawić swoje dane spowodowane skrzywionym rozmyciem. Spójrz na poniższy wykres:Podstawowa biblioteka korekcyjna języka Python

enter image description here

jestem całkiem blisko do osiągnięcia, czego chcę. Jak widać, próbuję dopasować wielomian do wszystkich moich danych, podczas gdy ja powinienem po prostu dopasować wielomian w lokalnych minimach.

Idealnie chciałbym mieć wielomian dopasowanie który po odjęciu od moich pierwotnych danych mogłoby spowodować coś takiego:

enter image description here

Czy istnieją wybudowany w bibliotekami, że robi to już?

Jeśli nie, to każdy prosty algorytm można dla mnie polecić?

+0

Możesz spróbować zaprojektować filtr o wysokiej ścieżce, przekształcając swój sygnał za pomocą '' rfft() '' i ustawiając część niskoczęstotliwościową na zero. – Dietrich

+0

Powinieneś przyjrzeć się minimalnym technikom wyszukiwania w tym pytaniu: http://stackoverflow.com/questions/24656367/find-peaks-location-in-a-spectrum-numpy. Gdy już to zrobisz, możesz zmieścić się tylko do minimów, aby znaleźć korektę linii bazowej. –

Odpowiedz

11

Znalazłem odpowiedź na moje pytanie, po prostu dzielę się dla wszystkich, którzy się na to natknęli.

Istnieje algorytm nazwany "Asymmetric Least Squares Smoothing" autorstwa P. Eilers i H. Boelens w 2005 roku. Papier jest bezpłatny i można go znaleźć w google.

def baseline_als(y, lam, p, niter=10): 
    L = len(y) 
    D = sparse.csc_matrix(np.diff(np.eye(L), 2)) 
    w = np.ones(L) 
    for i in xrange(niter): 
    W = sparse.spdiags(w, 0, L, L) 
    Z = W + lam * D.dot(D.transpose()) 
    z = spsolve(Z, w*y) 
    w = p * (y > z) + (1-p) * (y < z) 
    return z 
0

wiem, że to jest stare pytanie, ale stumpled na nim kilka miesięcy temu i wdrożone równoważną odpowiedź korzystając spicy.sparse rutyny.

# Baseline removal                        

def baseline_als(y, lam, p, niter=10):                   

    s = len(y)                        
    # assemble difference matrix                    
    D0 = sparse.eye(s)                      
    d1 = [numpy.ones(s-1) * -2]                    
    D1 = sparse.diags(d1, [-1])                    
    d2 = [ numpy.ones(s-2) * 1]                    
    D2 = sparse.diags(d2, [-2])                    

    D = D0 + D2 + D1                       
    w = np.ones(s)                       
    for i in range(niter):                     
     W = sparse.diags([w], [0])                   
     Z = W + lam*D.dot(D.transpose())                 
     z = spsolve(Z, w*y)                     
     w = p * (y > z) + (1-p) * (y < z)                  

    return z 

Cheers,

Pedro.