python: Was sind effiziente Techniken, um tief verschachtelte Daten flexibel zu handhaben?

8

Meine Frage bezieht sich nicht auf ein bestimmtes Code-Snippet, sondern eher auf allgemeine Informationen. Bitte tragen Sie mich also bei:

Wie sollte ich die Daten organisieren, die ich analysiere, und welche Tools sollte ich verwenden, um sie zu verwalten?

Ich benutze Python und Numpy, um Daten zu analysieren. Da die Python-Dokumentation anzeigt, dass Wörterbücher in Python sehr optimiert sind, und auch aufgrund der Tatsache, dass die Daten selbst sehr strukturiert sind, habe ich sie in einem tief verschachtelten Wörterbuch gespeichert.

Hier ist ein Skelett des Wörterbuchs: Die Position in der Hierarchie definiert die Art des Elements, und jede neue Zeile definiert den Inhalt eines Schlüssels in der Präzedenz-Ebene:

%Vor%

Bearbeiten: Um meinen Datensatz etwas besser zu erklären:

%Vor%

Der Typ von Operationen, die ich ausführe, ist zum Beispiel die Eigenschaften der Arrays zu berechnen (aufgelistet unter Ch1, Ch2), Arrays aufzunehmen, um eine neue Sammlung zu erstellen, zum Beispiel Antworten von N01 aus Region 16 (R16) eines gegebenen analysieren individuell zu verschiedenen Zeitpunkten, etc.

Diese Struktur funktioniert gut für mich und ist sehr schnell, wie versprochen. Ich kann den gesamten Datensatz ziemlich schnell analysieren (und das Wörterbuch ist viel zu klein, um den Ram meines Computers zu füllen: ein halbes Gig).

Mein Problem kommt von der umständlichen Art, in der ich die Operationen des Wörterbuchs programmieren muss. Ich habe oft Codeabschnitte, die so aussehen:

%Vor%

was hässlich, umständlich, nicht wiederverwendbar und spröde ist (muss für jede Variante des Wörterbuchs neu kodiert werden).

Ich habe versucht, rekursive Funktionen zu verwenden, aber abgesehen von den einfachsten Anwendungen, stieß ich auf einige sehr böse Bugs und bizarre Verhaltensweisen, die eine große Zeitverschwendung verursachten (es hilft mir nicht, mit pdb in ipython zu debuggen) wenn ich mich mit tief verschachtelten rekursiven Funktionen befasse). Am Ende ist die einzige rekursive Funktion, die ich regelmäßig verwende, die folgende:

%Vor%

Ich weiß, dass ich das falsch mache, weil mein Code lang, noodly und nicht wiederverwendbar ist. Ich muss entweder bessere Techniken verwenden, um die Wörterbücher flexibel zu manipulieren oder die Daten in ein Datenbankformat (sqlite?) Zu bringen. Mein Problem ist, dass ich, da ich (schlecht) autodidaktisch in Sachen Programmierung bin, keine praktische Erfahrung und Hintergrundwissen habe, um die verfügbaren Optionen zu schätzen. Ich bin bereit, neue Werkzeuge zu lernen (SQL, objektorientierte Programmierung), was immer nötig ist, um die Arbeit zu erledigen, aber ich zögere, meine Zeit und meine Bemühungen in etwas zu investieren, das für meine Bedürfnisse eine Sackgasse sein wird.

>

Was sind Ihre Vorschläge, um dieses Problem anzugehen und meine Tools auf eine kürzere, flexiblere und wiederverwendbare Weise zu codieren?

Nachtrag: Abgesehen von etwas mit einem bestimmten Unterwörterbuch des Datenwörterbuchs, hier sind einige Beispiele von Operationen, die ich für den Datensatz dic implementiert habe, oder ein Unterwörterbuch davon:

Tatsächlich habe ich einige rekursive Funktionen, die gut funktionierten:

%Vor%

Für einige Operationen habe ich keinen anderen Weg gefunden, als das Wörterbuch zu glätten:

%Vor%     
AlexandreS 30.03.2010, 09:23
quelle

5 Antworten

11
  

"Ich habe es in einem tief verschachtelten Wörterbuch gespeichert"

Und wie Sie gesehen haben, geht es nicht gut.

Was ist die Alternative?

  1. Zusammengesetzte Schlüssel und ein flaches Wörterbuch. Sie haben einen 8-teiligen Schlüssel: (Individuell, Imaging-Sitzung, Region abgebildet, Zeitstempel der Datei, Eigenschaften der Datei, Bereiche von Interesse in Bild, Format der Daten, Kanal der Akquisition) welche Karten zu einem Array von Werten.

    %Vor%

    Das Problem damit ist die Suche.

  2. Richtige Klassenstrukturen. Tatsächlich kann eine vollständige Klassendefinition übertrieben sein.

  

"Die Art der Operationen, die ich ausführe, ist zum Beispiel die Eigenschaften der Arrays zu berechnen   (aufgelistet unter Ch1, Ch2), nehmen Sie Arrays auf, um eine neue Sammlung zu erstellen, zum Beispiel analysieren   Antworten von N01 aus Region 16 (R16) einer bestimmten Person zu verschiedenen Zeitpunkten usw. "

Empfehlung

Verwenden Sie zuerst ein namedtuple für Ihr ultimatives Objekt.

%Vor%

Oder so ähnlich. Erstellen Sie eine einfache Liste dieser benannten Tupelobjekte. Sie können dann einfach über sie iterieren.

Zweitens, verwenden Sie viele einfache Map-Reduce-Operationen für diese Master-Liste der Array-Objekte.

Filtern:

%Vor%

Reduzieren durch gemeinsamen Schlüssel:

%Vor%

Dadurch wird eine Teilmenge in der Karte erstellt, die genau die gewünschten Elemente enthält.

Sie können dann indiuidual_dict ['AS091209M02'] durchführen und alle ihre Daten haben. Sie können dies für jeden (oder alle) der verfügbaren Schlüssel tun.

%Vor%

Dies kopiert keine Daten. Es ist schnell und relativ kompakt im Speicher.

Mapping (oder Transformation) des Arrays:

%Vor%

Wenn das Array selbst eine Liste ist, können Sie diese Liste aktualisieren, ohne das Tupel als Ganzes zu unterbrechen. Wenn Sie ein neues Array aus einem vorhandenen Array erstellen müssen, erstellen Sie ein neues Tupel. Es ist nichts falsch daran, aber es ist ein neues Tupel. Du fährst mit solchen Programmen.

%Vor%

Sie können Transformationen, Reduktionen, Zuordnungen zu komplizierteren Dingen aufbauen.

Das Wichtigste ist, dass Sie nur die Wörterbücher erstellen, die Sie von der Hauptliste benötigen, damit Sie nicht mehr als nur minimal filtern.

Übrigens. Dies kann trivial einer relationalen Datenbank zugeordnet werden. Es wird langsamer, aber Sie können mehrere gleichzeitige Aktualisierungsvorgänge durchführen. Abgesehen von mehreren gleichzeitigen Aktualisierungen bietet eine relationale Datenbank keine darüber liegenden Funktionen.

    
S.Lott 30.03.2010, 10:26
quelle
2

Sie können Ihre Schleifen besser aussehen lassen, indem Sie Folgendes ersetzen:

%Vor%

mit

%Vor%

Damit erhalten Sie Zugriff auf alle Werte mit einem relativ knappen Code. Wenn Sie auch einige Schlüssel benötigen, können Sie Folgendes tun:

%Vor%

Je nach Ihren Anforderungen können Sie auch ein einzelnes Wörterbuch mit Tupelschlüsseln erstellen und verwenden:

%Vor%     
EOL 30.03.2010 09:45
quelle
1

Ich werde einige Gedanken darüber teilen. Anstelle dieser Funktion:

%Vor%

Was möchten Sie einfach schreiben als:

%Vor%

Es gibt 2 Möglichkeiten. Eins ist funktional, das zweite ist generatorartig. Der zweite ist:

%Vor%

Damit können Sie die Logik des Wörterbuchs erfassen. Es ist sehr einfach, diese Funktion zu modifizieren, um verschiedene Arten des Durchgehens der Struktur zu unterstützen. Es hängt davon ab, wie sich Ihre Struktur ändert, wenn es nur eine Tiefe der Schleife oder etwas anderes ist. Könnten Sie etwas ausführlichere Beispiele zu den Anforderungen für die Baumstruktur veröffentlichen? Wie filtern, suchen etc.? Die Tiefe würde so aussehen (ungetestet) - es ergibt ein Paar (Tupel von Schlüsseln), (Wert):

%Vor%

Jetzt wird es einfacher:

%Vor%

Es gibt noch andere Möglichkeiten, dies anzupassen. Sie könnten einen benannten Tupel-Typ als Parameter von deep_loop hinzufügen. Deep_loop könnte die Tiefe vom benannten Tupel automatisch erkennen und das benannte Tupel zurückgeben.

    
ondra 30.03.2010 10:58
quelle
0

Sie fragen: Wie soll ich die Daten organisieren, die ich analysiere, und welche Tools sollte ich verwenden, um sie zu verwalten?

Ich vermute, dass ein Wörterbuch trotz all seiner Optimierung nicht die richtige Antwort auf diese Frage ist. Ich denke, Sie wären besser dran mit XML oder, wenn es eine Python-Bindung dafür gibt, HDF5, sogar NetCDF. Oder, wie Sie selbst vorschlagen, eine Datenbank.

Wenn Ihr Projekt von ausreichender Dauer und Nützlichkeit ist, um zu lernen, wie man solche Technologien einsetzt, dann werden Sie feststellen, dass es jetzt besser ist, sie zu lernen und die richtigen Datenstrukturen zu finden, als mit den falschen Daten zu kämpfen Strukturen für das gesamte Projekt. Das Erlernen von XML oder HDF5 oder SQL oder was auch immer Sie wählen, baut Ihre allgemeine Expertise auf und macht Sie besser in der Lage, das nächste Projekt anzugehen. Das Einhalten von problematischen, problemspezifischen und idiosynkratischen Datenstrukturen führt beim nächsten Mal zu denselben Problemen.

    
High Performance Mark 30.03.2010 10:08
quelle
0

Sie könnten eine Generatorfunktion schreiben, mit der Sie über alle Elemente einer bestimmten Ebene iterieren können:

%Vor%

Welches kann dann wie folgt verwendet werden:

%Vor%

Wenn Sie auch Elemente filtern müssen, könnten Sie zuerst alle Elemente erhalten, die gefiltert werden müssen (zB die 'rgk' Ebene):

%Vor%

Zumindest wird es dadurch leichter, mit einer Hierarchie von Wörterbüchern zu arbeiten. Die Verwendung von aussagekräftigeren Namen würde ebenfalls helfen.

    
Pieter Witvoet 30.03.2010 10:24
quelle

Tags und Links