Datenhandling mit mehreren Dateien

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin ihr Leser,

ich stehe vor folgender Aufgabe:

Nehme aus n-verschiednen Datein einen Wert (=Zeile mit mehrern Einträgen) und verarbeite die einzelen Werte mit anderen aus einer und oder mehrern Datein.

Die Verarbeitung läuft soweit zufrieden stellen. Nur der erste Teil ist unheimlich zäh. Ich habe schon Verschiedenes ausprobiert.
N-verschieden Dateien in Listen/Feld geht auf den Speicher.
Datei öffnen Wert herauspicken und verarbeiten dauert eben und die Datein werden x-mal geöffnet.

Meine letzter Stand war die n-Datein zuöffnen und die Lese-Iteratoren zeilenweise weiter zu inkrementiern, was aber leider auch nicht zu einer Beschleunigung geführt hat.

Da ich schon Verschiedenes ausprobiert habe, hoffe ich nun eine Lösung übersehen zu haben.

In der Hoffnung auf euren Rat
bis bald und Dankeschön
BlackJack

@BerndB: Die Frage ist zu allgemein um da mehr als was allgemeines zu zu sagen. Also der allgemeine Hinweis: Wäre das etwas für eine Datenbank?
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin BlackJack,

die Frage ist allgemein, weil ich auch für mich versuchen wollte das wesentliche Problem zu definieren/erkennen.

Prinzipiell könnte man die verschiedenen Dateien von den ich gleichzeitig nur eine Zeile, also zu einem
Objekt gehörenden Datensatz für die Verarbeitung benötige als Datenbank betrachten. Leider fehlt mir in diesem Bereich die Erfahrung. Da meine Bearbeitung in Python schon vorliegt, wie kann ich hier eine Datenbank anbinden? Muß ich die einzelenen Dateien nicht auch in die Datenbank laden, und wie schnell geht das und der dann folgende Zugriff? Habe ich dann nicht auch alles im Hauptspeicher liegen? Welche Datenbank ist für einen Einsteiger wie mich für eine Art Tabelle mit n(Datein)*m(Spalten der Datei) Spalten zu empfehlen?

Ich habe gerade nochmal hier im Forum gestöbert - sollte man doch vorher machen - es gibt schon eine
Flut von Schnittstellen. Welche ist für mich optimal wenn ich wirklich nur eine Art von Tabelle ohne Analyse und Querverweise brauch ? Was ist von PyTable zu halten ? Ich möchte, wenn möglich, später nur eine Installation meines Tools (in Python) vornehmen müssen und nicht noch fremde Softwarepakete dazupacken.

Trotzdem vielen Dank und
bis bald
Bernd
BlackJack

@BerndB: Wie gesagt: Die Informationen sind zu dünn. Wenn man eine gute, oder in diesem Fall potentiell bessere, Datenstruktur sucht, ist es wichtig zu wissen was das für Daten sind, und wie die Anfragen an diese Daten passieren werden, also einmal das wie und zum anderen die jeweilige erwartete Häufigkeit. Denn nach diesen Informationen wählt man ja die passende Datenhaltung aus.
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin nochmal,

okay, dann will ich die Daten mal etwas dicker machen.

In den n-Datein stehen jeweils Zeilenweise als erste ein IdentNr. und dann 3 Float-Werte.
Zu jeder n-Datei gehört eine weitere, eine Art-Zeitverlauf, mit der die 3-Float-Werte transformiert werden.
Wie gesagt ist die Transformation nicht das Problem, sonderen das Bereitstellen der jeweiligen zur IdentNr. gehörenden
3*n Float-Werte. Die Anzahl der Zeilen kann durch aus die 40000 und evntuell auch mehr erreichen. Nach der Transformation wird das zur IdentNr. gehörende Ergbenis abgespeichert die 3*n Float-Werte werden dann nicht mehr benötigt, der Vorgang fährt mit der nächsten Zeile der n-Datein / IdentNr. fort. Es liegt also eine 2D-Feld (Tabelle) mit eindeutigen Zeilenbezeichnern (IdentNr) in der ersten Spalte und n*3 weitere Spalten vor, die jedoch auf mehrere (n) Dateien zerlegt ist. Pro IdentNr ist der Dateizugriff nur einmal an der entsprechenen Zeile erforderlich. Daher auch mein letzter Stand auf alle n-Datein einen Lese-Iterator zu starten und n-mal abzufragen um die jweiligen 3-Float-Werte zu bekommen und nicht alle Datein in den Speicher zu laden, obwohl ich hoffte hierbei die Plattenlesenzeit zu umgehen. Beide
Varianten brachten jedoch keinen Fortschritt in Verarbeitungsdauer, zumal der Speicherbedarf deutlich größer als die Summe der Dateigrößen war.

In der Hoffnung etwas mehr Licht ins Dunkel gebracht zu haben
Bernd
BlackJack

Etwas mehr Licht ja, aber immer noch etwas trübe. Das mag aber auch an mir liegen. :-)

Sind die Datenzeilen in den `n` Dateien denn "parallel", also belegen die Werte für die selbe Ident-Nummer in jeder Datei die gleiche Zeilennummer? Dann wäre das parallele Lesen der Dateien in der Tat vom Speicherverbrauch und der Geschwindigkeit zumindest algorithmisch wohl mit das Beste was man machen kann. Und mit `itertools.izp()` lässt sich das iterieren auch recht knapp formulieren. Wenn die "Verrechnung" mit einer Funktion passiert bietet sich auch `itertools.imap()` an.
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin BlackJack,

die Daten liegen in der Tat parallel vor, d. h. in Zeile z von Datei a steht die gleiche IdentNr. wie in Zeile z von Datei b.
Hab mein Problem jetzt soweit beschleunigt, dass ich über seek() die Position vom ersten Datei-Iterator an die n-1 weiteren
übergebe. Zeitbedarf ist jetzt gegenüber meiner Verabreitung nicht mehr messbar. Ich werde mir aber die itertools auch nochmal anschauen. Jetzt bremst die Verarbeitung meiner Daten.
Wie ziehe ich die Matrix eines Kreuzproduktes zweier Vektoren (1,6)x(12000,1) (M=[[ai*bi for ai in A] for bi in B]) möglichst schnell auf und wie deren Addition mit einer gleicher Dimensionierung (6x12000)(mach ich zur Zeit mit zwei geschachtelten map() Läufen)?
Werde mir hierfür mal NumPy anschauen, aber vielleicht geht es ja auch mit den Standartfunktionen schneller.

Vielen Dank für die konstruktive und hilfreiche
Konversation und die gespendete Zeit
bis bald
Bernd
BlackJack

@BerndB: Das mit `seek()` funktioniert!? Dann müssen ja die Zeilen in allen Dateien die gleiche Länge haben. Und Du gehst Die nicht linear durch, sondern "springst" an bestimmte Zeilen!?
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin nochmal,

ja die Zeilen sind alle gleich lang. Wenn mal in ferner Zukunft alles fertig ist, dann kann es durchaus vorkommen, dass
nicht alle Zeilen / IdentNr. bearbeitet werden. Daher gibt es eine Indexdatei die die zubearbeitenden IdentNr. enthält und im ersten Lese Iterator eine Abfrage ob eine entsprechende IdentNr. erreicht wurde (hm, vielleicht kann man hier besser eine filter()-Funktion verwenden - mal schauen). Meine Zeitersparnis liegt also in dem nicht n-1-mal wiederholten Abfragen. In der Regel sollen aber alle IdentNr. verarbeitet werden und so die n-Dateien zeilenweise 'linear' bedient werden.

Mein Ziel ist es die Beabeitung von 20000IdentNr./h, z. Zeit. liege ich bei 36 IdentNr./h.

Mit den itertools muß ich erst noch eine Weile spielen, um zu sehen ob ich hiermit noch was herauskitzeln kann.

Grüße
Bernd
BlackJack

@BerndB: Ich glaube mir ist der Zugriff immer noch nicht ganz klar. Was bekommst Du in jedem Schritt? Eine mehr oder weniger zufällige Identnummer zu der Du dann die entsprechenden Zeilen aus den Dateien heraussuchst, oder arbeitest Du die Zeilen in den Schritten der Reihe nach ab? Letzteren Fall nahm ich bis jetzt an, aber dann verstehe ich nicht wie `seek()` einen Vorteil darstellen sollte?

Wenn es ersteres ist, also "zufällige" Identnummern abfragen, und die Zeilen tatsächlich alle eine fixe Länge haben, dann würde sich ein Index lohnen, also einfach ein Dictionary Identnummer nach Zeilennummer, also eine Datensatznummer. Daraus lässt sich dann der Wert für `seek()` für alle Dateien berechnen.
BerndB
User
Beiträge: 14
Registriert: Freitag 28. Mai 2010, 15:49

Moin BlackJack,

das seek() bringt nur dann einen Vorteil, wenn ich in den n-Datein mehr IdentNr=Zeilen habe als in meiner
Liste der zubearbeitenden IdentNr. Dann werden Lücken zwischen den IdentNr=Zeile vom ersten Iterator erkannt und an die n-1-Iteratoren als Sprung weiter gereicht(keine erneute Suche in Richtung Dateiende erforderlich). Arbeite ich alle IdentNr=Zeilen ab, Zeil für Zeile ohne Lücken wird ein Null-Sprung weiter gereicht. Die List der abzuarbeitenden IdentNr. muß in der gleichen Rangfolge wie die Zeilen der n-Datein sortiert sein. Die n-Datein werden von Vorn nach Hinten abgetastet und es wird nicht vom Ende wieder an den Anfang/Mitte oder sonst wohin gesprungen.

Bis bald
Bernd
BlackJack

@BerndB: Dann würde ich sagen klingt das schon recht effizient. Vorher einmal drübergehen und eine Indexdatenstruktur zu erzeugen würde, wenn überhaupt, nur was bringen wenn mehrmals mit jeweils einem Satz Identnummern über die Daten iteriert werden müsste.
Antworten