2 Stimmen

Python Rpy R Datenverarbeitung Optimierung

Ich schreibe ein Datenverarbeitungsprogramm in Python und R, überbrückt mit Rpy2.

Da es sich bei den Eingabedaten um binäre Daten handelt, verwende ich Python, um die Daten auszulesen und sie an R weiterzugeben, um dann die Ergebnisse für die Ausgabe zu sammeln.

Die Daten sind in Stücke aufgeteilt, die jeweils etwa 100 Bytes umfassen (1 Byte pro Wert * 100 Werte).

Sie funktionieren gerade noch, aber die Geschwindigkeit ist sehr gering. Hier sind einige meiner Tests auf 1GB Größe (das heißt, 10^7 Stücke) von Daten:

Wenn ich Rpy2-Aufrufe deaktiviere, um einen Trockenlauf zu machen, dauert es etwa 90 Minuten, bis Python auf einem Intel(R) Xeon(TM) CPU 3.06GHz mit einem einzigen Thread eine Schleife durchlaufen hat.

Wenn ich die volle Funktionalität und Multithreading auf dem Xeon Dual Core aktiviere, dauert es (nach Schätzung) ~200 Stunden, bis das Programm fertig ist.

Ich habe das Python-Programm mehrere Male beendet, der Aufrufstapel zeigt fast immer auf die Rpy2-Funktionsschnittstelle. Ich habe auch Profiling, die ähnliche Ergebnisse gibt.

All diese Beobachtungen deuten darauf hin, dass der R-Teil, der von Rpy2 aufgerufen wird, der Flaschenhals ist. Also habe ich eine eigenständige Version meines R-Programms profiliert, aber die Zusammenfassung der Profilierung zeigt auf "Anonymous". Ich versuche immer noch herauszufinden, welcher Teil meines R-Skripts die meiste Zeit in Anspruch nimmt. ****Aktualisiert, siehe meine Bearbeitung unten*****

Es gibt zwei verdächtige Kandidaten, zum einen eine kontinuierliche Wavelets-Transformation (CWT) und Wavelets-Transformationsmodul-Maxima (WTMM) unter Verwendung von wmtsa aus cran[1], zum anderen eine nichtlineare Anpassung der Ex-Gaussionskurve.

Was mir dazu einfällt, sind:

  1. für die Anpassung könnte ich R-Routing durch Inline-C-Code ersetzen? es gibt viele Anpassungsbibliotheken in C und Fortran... (Idee aus dem Netz; ich habe das nie gemacht; unsicher)

  2. für Wavelet-Algorithmen.... Ich müsste das wmtsa-Paket analysieren, um Hotspots in C? .... neu zu schreiben. Eine Neuimplementierung des gesamten wmtsa-Pakets in C oder Fortran wäre für mich nicht sehr trivial. Ich habe nicht viel Programmiererfahrung.

  3. Die Daten in der Datei sind in 20 aufeinanderfolgenden Bytes organisiert, die ich direkt auf ein C-ähnliches char*-Array abbilden könnte? derzeit liest mein Python-Programm nur ein Byte nach dem anderen und hängt es an eine Liste an, was langsam ist. Dieser Teil des Codes dauert 1,5 Stunden im Vergleich zu ~200 Stunden für R, also nicht so dringend.

Dies ist das erste Mal, dass ich die Effizienz des Programms bei der Lösung echter Probleme erlebe. Ich STFW und fühlte mich überwältigt von den Informationen. Bitte geben Sie mir einige Ratschläge, was als nächstes zu tun und wie.

Zum Wohl!

Fußnoten:

  1. http://cran.r-project.org/web/packages/wmtsa/index.html

* Aktualisieren *

Dank der proftools von cran konnte ich einen Call-Stack-Graphen erstellen. Und ich konnte sehen, dass ~56% der Zeit auf wmtsa verbracht werden, Code-Schnipsel ist wie:

W <- wavCWT(s,wavelet="gaussian1",variance=1/p) # 1/4
W.tree <-wavCWTTree(W) # 1/2
holderSpectrum(W.tree) # 1/4

~28% der Zeit wird auf nls verwendet:

nls(y ~ Q * dexGAUS(x, m, abs(s), abs(n)) + B, start = list(Q = 1000, m = h$time[i], s = 3, n = 8, B = 0), algorithm="default", trace=FALSE)

wobei die Auswertung von dexGAUS aus dem Paket gamlss.dist den größten Teil der Zeit in Anspruch nimmt.

die restlichen ~10% der R-Zeit werden für Datenübergabe/Split/Aggregation/Subset verwendet.

1voto

John Punkte 22733

Für Option 3... erhalten Ihre Daten in effizient... lesen Sie es alle in als eine lange str Typ in Python mit einem einzigen lesen aus der Datei. Nehmen wir an, es heißt myStr.

import array
myNums = array.array('B', myStr)

Jetzt myNums ist ein Array von jedem Byte leicht konvertiert... siehe help(array.array)... in der Tat, wenn man sich das anschaut, sieht es so aus, als ob man es direkt aus einer Datei auf diese Weise durch das Array bekommen kann.

Damit sollten Sie 1,4 Stunden Ihres Datenbestandes loswerden.

1voto

lgautier Punkte 11136

Ich gehe davon aus, dass Sie das haben:

  • Python-Code, der rpy2 an einigen Stellen verwendet

  • Leistungsprobleme, die auf Aufrufe von rpy2 zurückgeführt werden können

  • die Leistungsprobleme scheinen derzeit nicht viel mit rpy2 selbst zu tun zu haben, da das zugrunde liegende R weitgehend für die Laufzeit verantwortlich ist

  • ein Teil Ihres R-Codes bestand darin, Bytes einzeln zu lesen und an eine Liste anzuhängen, was Sie verbessert haben, indem Sie diesen Teil nach Python verschoben haben

Es ist schwer zu sagen, wie man helfen kann, ohne den eigentlichen Code zu sehen, aber vielleicht sollten Sie das in Betracht ziehen:

  • eine Pufferungsstrategie für das Lesen von Bytes (da dies bereits von John beantwortet wurde).

  • an der Optimierung Ihres R-Codes arbeiten

  • eine triviale Parallelisierung in Betracht ziehen (und eventuell Rechenkapazität in der Cloud mieten)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X