2017-03-24 7 views
0

Ich lese in einer Datei mit zwei Spalten mit numerischen Daten. Sei die erste Spalte 'x' und die zweite Spalte 'y'.Python diskrete Differenzierung

Die Daten in 'x' sind nicht gleichmäßig verteilt. Das heißt, es geht ungefähr so:

2,4 2,6 2,7 3,0 3,2 3,5 ...

Die Daten offensichtlich endlich ist. Es hat einen Anfangs- und einen Endwert.

Ich muss "Diskontinuitäten" in diesen Daten finden. Das mag ich die Daten meiner Differenzierung tun: dy/dx

ich eine Suche gemacht habe, aber alle Differenzierung Antworten fand ich eine analytische Funktion beinhalten, wie zum Beispiel y = x ** 2 + 1

Meine Daten sind diskret und passen nicht zu einer analytischen Funktion. Ich muss die Ableitung für jeden Wert von 'x' über diese Daten finden, wobei zu beachten ist, dass 'x' nicht gleichmäßig verteilt ist.

Angenommen, ich habe die Daten aus meiner Datendatei eingelesen und in den Variablen 'x' und 'y' gespeichert.

Jetzt möchte ich dy/dx, und ich möchte dy/dx vs x plotten.

Was kann ich "importieren", das dieses Derivat macht? Oder muss ich den Algorithmus selbst schreiben?

+0

Erstens, was hast du bisher versucht? Bitte posten Sie Ihren Code. Das hängt wirklich davon ab, was Sie mit einer Diskontinuität meinen. Wie definierst du das? Wollen Sie nur mit dem Auge feststellen, ob ein Sprung in der Ableitung aus der Darstellung besteht? – James

+0

Ich habe nichts versucht, weil alle Unterscheidungsroutinen, die ich in SciPy und anderen Paketen gefunden habe, eine einheitliche Schrittgröße = h erforderten. Meine Schrittgröße ist nicht einheitlich, wie ich ursprünglich sagte. Ich brauche nur etwas, um die Differenzierung des Datums zu tun. "Warum" ist nicht wichtig. – Mannix

+0

Sie müssen definieren, was eine Unstetigkeit ist. Dann können Sie darüber nachdenken, wie Sie die Prüfung durchführen - am wahrscheinlichsten mit einem nicht zu schwierig handgeschriebenen Code. –

Antwort

0

Ich würde the algorithm selbst schreiben. Es gibt keinen eingebauten Import, der dies tut. Hier ist ein Code als Ausgangspunkt zu verwenden:

>>> xarr = [2.4, 2.6, 2.7, 3.0, 3.2, 3.5, 3.8, 4.1, 5.3] 
>>> yarr = [10, 12, 18, 20, 22, 27, 30, 32, 36] 
>>> [(y2-y0)/(x2-x0) for x2, x0, y2, y0 in zip(xarr[2:], xarr, yarr[2:], yarr)] 
[26.666666666666643, 20.000000000000004, 8.0, 
14.0, 13.333333333333341, 8.333333333333337, 4.0] 

Sie können die Annäherungen verfeinern, indem jede Seite Gewichtung entsprechend dem Abstand von der Mitte von drei Punkten, aber das ist wahrscheinlich nicht notwendig, wenn alles, was Sie tun sucht nach Diskontinuitäten.

+0

Kann ich diese letzte Zeile einer Variablen zuweisen? Wie dy = [(y2-y0)/(x2-x0) für x2, x0, y2, y0 in zip (xarr [2:], xarr, yarr [2:], yarr)] – Mannix

+0

Das würde funktionieren .Die Werte entsprechen abgeleiteten Schätzungen für "xarr [1: -1]". –

+0

Sollte es nicht 'zip (xarr [1:], xarr, yarr [1:], yarr)' sein? Im Moment vergleichen Sie Werte, die zwei Indizes voneinander entfernt sind, statt einer. – Junuxx

0

Ich schrieb einen einfachen Algorithmus, der mein Array in kleinere Felder von 3 Punkten aufteilt. Passe dann eine Funktion zweiter Ordnung durch diese drei Punkte an, nimm dessen Ableitung und berechne den Wert am mittleren Punkt. Für die Endpunkte verwende ich nur zwei Werte.

Es ist ein bisschen chaotisch. Und ich weiß, dass es effizientere Möglichkeiten gibt, die Schleife zu machen. Hier ist, was ich getan habe:

dydx=[] 

for i in range(len(x)): 
    if i==0: 
     dx=x[i:i+2] 
     dy=y[i:i+2] 
     order=1 
    elif i==len(x)-1: 
     dx=x[i-1:i+1] 
     dy=y[i-1:i+1] 
     order=1 
    else: 
     dx=x[i-1:i+2] 
     dy=y[i-1:i+2] 
     order=2 
    z=np.polyfit(dx,dy,len(dx)-1) 
    f=np.poly1d(z) 
    df=np.polyder(f) 
    dydx.append(float(df(x[i]))) 
dydx=np.array(dydx) 

Irgendwelche Vorschläge zur Reinigung dieser Schleife nach oben in einer Weise, dass die if-elif-Anweisungen beseitigt?