Lesen großer Files mit netcdf4-python

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
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

Hallo, bin noch neu im Umgang mit netcdf4-python. Habe ein paar sehr große *.nc-files (25GB), die ich einlesen möchte. Bei kleinen Files klappt das auch, aber bei den großen kommt folgende Fehlermeldung:

File "netCDF4.pyx", line 1314, in netCDF4.Dataset.__init__ (netCDF4.c:14697)
RuntimeError: Invalid argument

Der code dazu sieht wie folgt aus:

Code: Alles auswählen

from netCDF4 import Dataset
rootgrp = Dataset('Y:\largefile.nc', 'r')
rootgrp.close()
Meine Suche zu dem Problem im Internet war leider erfolglos. Ich bin dankbar für jeden Tipp!

Ich benutze netcdf4-python 0.9.9, python 2.7 unter windows xp.

Gruß, Julia
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Ich kann mir vorstellen, dass die Dateien nunmal zu groß sind. Du kannst normalerweise nicht einfach 25 GB in deinen RAM kopieren. Hab aber jetzt keine Lust darauf, in der mehr als 43.000 (!) Zeilen langen Datei nach der Stelle zu suchen, wo steht, wie die Dateien eingelesen werden …
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

und gibt es eine möglichkeit das einlesen effizienter zu gestalten? also bei python kann man ja z.B. mit xreadlines() immer nur eine zeile lesen, statt mit readlines() das ganze file zu lesen. vielleicht würde mir eine ähnliche methode für netcdf4 helfen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

``xreadlines`` ist doch obsolet. Du kannst über ein Dateiobjekt direkt iterieren:

Code: Alles auswählen

with open(...) as handler:
    for line in handler:
        do_something(line)
Das klappt zumindest bei Textdateien - bei Binärdateien dürften das die einzelnen Bytes sein, über die iteriert wird (da wäre der Name ```line`` dann irreführend).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

Danke für eure Antworten! Ich bin dabei, das nc-file irgendwie zu splitten. Aber um nochmal auf netcdf4python einzugehen, gibt es denn eine Möglichkeit nur eine Variable aus dem nc-file anzusprechen, ohne das ganze file im Speicher zu haben? Was genau macht denn "dataset(*.nc)" überhaupt? Ich hab das Gefühl, dass da das ganze file eingelesen wird...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich kenne dieses Framework nicht. Aber wenn es in dem Kontext generell sehr große Dateien gibt, dann wird es doch wohl dafür ausgelegt worden sein, dass Dateien nur iterativ eingelesen werden?! Im Zweifel musst Du in die Doku gucken.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

So, ich werde nun die nc-files mit dem nco packet splitten, um dann mit python weiter zu arbeiten. Damit ist das Thema erstmal beendet. Danke für eure Antworten!
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

nomnom hat geschrieben:Hab aber jetzt keine Lust darauf, in der mehr als 43.000 (!) Zeilen langen Datei nach der Stelle zu suchen, wo steht, wie die Dateien eingelesen werden …
Wobei du dir da auch den von Cython generierten Code rausgesucht hast. Den möchte man nicht wirklich lesen. Wenn, dann doch lieber die zughörige netCDF4.pyx. :)
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

Hallo, hier noch ein Nachtrag.

Das mit dem Aufsplitten des riesigen Files hat funktioniert. Das Einlesen mit netcdf4-python ergab trotzdem noch den gleichen Fehler wie im ersten Beitrag beschrieben. Durch Zufall habe ich nun herausgefunden, dass beim Einlesen Doppel-Backslashes nötig sind:

Code: Alles auswählen

rootgrp = Dataset('Y:\\largefile.nc', 'r')
statt

Code: Alles auswählen

rootgrp = Dataset('Y:\largefile.nc', 'r')
Ich weiß zwar nicht warum, schließlich hat es bei anderen nc-Dateien auch mit nur einem Backslash funktioniert. Auf jeden Fall kann ich so jetzt die Dateien ordentlich einlesen.
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Julia hat geschrieben:Durch Zufall habe ich nun herausgefunden, dass beim Einlesen Doppel-Backslashes nötig sind:

Code: Alles auswählen

rootgrp = Dataset('Y:\\largefile.nc', 'r')
statt

Code: Alles auswählen

rootgrp = Dataset('Y:\largefile.nc', 'r')
Ich weiß zwar nicht warum, schließlich hat es bei anderen nc-Dateien auch mit nur einem Backslash funktioniert.
Das liegt daran, dass Backslashes Escapesequenzen einleiten, wie z. B. „\n“ (Linefeed), „\t“ (Tabulator), „\a“ (Bell). Es gibt allerdings zu manchen Buchstaben keine Escapesequenzen: Z. B. dem „L“:

Code: Alles auswählen

In [5]: print '\l'
\l
Allerdings heißt deine Datei vermutlich nicht largefile.nc sondern irgendwie anders. ;)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Statt dem manuellen verdoppeln bieten sich raw Strings an:

Code: Alles auswählen

In [1]: r'\n'
Out[1]: '\\n'
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hach ja. Das Leben könnte so einfach sein, wenn Fehlermeldungen manchmal ein bißchen klarer wären... :)
Julia
User
Beiträge: 6
Registriert: Mittwoch 8. Februar 2012, 16:28

Ja, schön blöd... hab auch eben festgestellt, dass es überhaupt kein Problem ist, das 25GB-file mit netcdf4-python zu bearbeiten.... alles nur wegen einem fehlenden Backslash! Aber so kann ich mir jetzt einen Haufen Arbeit sparen :D
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

snafu hat geschrieben:Hach ja. Das Leben könnte so einfach sein, wenn Fehlermeldungen manchmal ein bißchen klarer wären... :)
Oder die Snippets nicht nachträglich bearbeitet werden würden. ;)
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Julia hat geschrieben:Ja, schön blöd... hab auch eben festgestellt, dass es überhaupt kein Problem ist, das 25GB-file mit netcdf4-python zu bearbeiten.... alles nur wegen einem fehlenden Backslash! Aber so kann ich mir jetzt einen Haufen Arbeit sparen :D
Und du weißt jetzt hoffentlich auch, dass Windowspfade (wegen dem Backslash) immer als Rawstring geschrieben werden sollten. ;)
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Oder man nimmt os.path.join zum Zusammenbasteln, und nur den Laufwerksbuchstaben als Rawstring
Antworten