Seite 1 von 1
netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 08:56
von derbernd
Hallo,
ich teste gerade python als Alternative zu Matlab. In Matlab kann man recht unkompliziert mit netCDF-Files umgehen und die meisten Befehle konne ich auf python übertragen.
Da ich relative große Datenmengen verarbeiten möchte und nur Teilbereiche der Datenmenge benötige, lese ich mir in Matlab nur eine Auswahl ein.
Code: Alles auswählen
data = netcdf.getVar(ncid, varid, [0 0 timeStart], [sizex sizey timeDiff+1]);
Mittels python würde ich die Daten so:
auslesen, wobei innerhalb der letzten Klammer ein Bereich stehen würde.
Wie kann ich dynamisch einen Vektor (Matlab) angeben, der mir ermöglicht nur einen Teilbereich auszulesen.
Danke
Nachtrag: Analog zu dem Beispiel auf Folie 13 und 14
http://snowball.millersville.edu/~adeca ... -files.pdf
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 09:23
von snafu
derbernd hat geschrieben:Mittels python würde ich die Daten so:
auslesen, wobei innerhalb der letzten Klammer ein Bereich stehen würde.
Ist das nicht bereits die Antwort auf deine Frage? Genau so greift man in Python auf Teilbereiche von sequenzartigen Typen zu. Nur wenn ein Typ diese Art des Zugriffs nicht unterstützt, dann muss man andere Wege finden. Ist deine Frage vielleicht so gemeint, dass du mit einem Objekt arbeiten musst, dass die besagte Unterstützung nicht eingebaut hat?
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 09:27
von derbernd
unsicher... Gibt es eine Möglichkeit die [:] mit einen Vektor dynamisch zu ersetzen?
aus [:] sollte [timeDiff, height, lat, lon] werden
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 09:32
von BlackJack
@snafu: Die Frage ist so gemeint das der OP gerne so ein Slice aus der Datei haben möchte ohne vorher das gesamte Array aus der Datei in den Speicher zu lesen. Hinter ``f.variables['lat']`` steckt nämlich ein Ladevorgang aus der netCDF-Datei.
@derbernd: Die Frage im letzten Beitrag habe ich nicht verstanden!?
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 09:33
von MagBen
Mit netCDF habe ich bisher noch nicht gearbeitet, aber mit hdf5.
"netCDF version 4 has many features not found in earlier versions of the library and is implemented on top of HDF5" (
https://pypi.python.org/pypi/netCDF4/0.8.2)
Beim Zugriff auf hdf5 kanst Du mit der Slicing-Syntax Teil-Arrays auslesen:
Es werden 2000 Elemente aus dem Array 'lat' gelesen von Element 2000 (einschließlich) bis Element 4000 (ausschließlich).
derbernd hat geschrieben:aus [:] sollte [timeDiff, height, lat, lon] werden
Code: Alles auswählen
lat = f.variables['lat'][:]
lat.shape = (timeDiff, height, lat, lon)
Das geht aber nur wenn gilt
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 09:42
von derbernd
@MagBen: Danke für den Ansatz. Es gibt ein Verständnisproblem bei deinem Code. Mittels
lese ich doch die gesamten Daten aus und mittels *.shape verändert man doch die Größe des Feldes. Somit habe ich vielleicht einen Teil, jedoch muss ich erstmal die gesamte Datenmenge einlesen.
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 10:03
von MagBen
derbernd hat geschrieben:lese ich doch die gesamten Daten aus und mittels *.shape verändert man doch die Größe des Feldes. Somit habe ich vielleicht einen Teil, jedoch muss ich erstmal die gesamte Datenmenge einlesen.
Das hängt davon ab, wie es implementiert ist.
lat_node wäre in hdf5 kein Numpy-Array mit den Daten, sondern ein Node-Objekt zum Zugriff auf die Daten.
jetzt würde in hdf5 ein Teil des Arrays gelesen werden und Dir als Numpy-Array zurückgegeben werden.
Wenn 'lat' ein 1D-Array in der Datei ist, dann ist auch lat_part ein 1D-Array, das Du aber auf beliebige Dimensionen ändern kannst, ohne dass Speicher neu angelegt oder Daten kopiert werden. Die Anzahl der Elemente darf sich dabei aber nicht ändern.
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 10:05
von BlackJack
@MagBen: Das mit dem Shape habe ich nicht verstanden!? ``f.variables['lat'][2000:4000]`` liefert doch schon ein Array mit der richtigen Form, also *kein* 1D-Array (es sei denn man hat tatsächlich nur eine Dimension in der Variable gespeichert).
@derbernd: Diesen Teil habe ich nicht verstanden: „aus [:] sollte [timeDiff, height, lat, lon] werden”. Auf jeden Fall scheint „slicing” die Antwort auf Dein Problem zu sein. Du musst halt nur noch heraus finden wie Du das Argument für den Indexzugriff gestalten musst, damit Du das gewünschte Ergebnis bekommst.
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 10:09
von derbernd
Ich teste dies heute Nachmittag und werde gegebenenfalls eine Lösung bzw. weitere Fragen posten
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 10:18
von MagBen
BlackJack hat geschrieben:``f.variables['lat'][2000:4000]`` liefert doch schon ein Array mit der richtigen Form, also *kein* 1D-Array (es sei denn man hat tatsächlich nur eine Dimension in der Variable gespeichert).
Kann sein, kann auch nicht sein. Dazu müsste ich wissen welche Dimension das Array lat in der Datei hat. Wenn es 1D ist, dann kann man die Dimension durch eine Zuweisung zu shape nachträglich verändern. Ist es dagegen schon so 4D wie es gebraucht wird, dann kann man shape auch verändern, braucht es aber vielleicht gar nicht.
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 11:01
von BlackJack
@MagBen: Wenn die Daten nicht als mehrdimensionales Array gespeichert sind, dann müsste man beim Slicen ja auch aufpassen das man einen richtigen Anfang und eine korrekte Länge berechnet. Das wäre nervig, fehleranfällig, und das Dateiformat und die Bibliothek nehmen einem das auch alles ab. Das wäre echt sehr unsinnig ein eigendlich mehrdimensionales Array ”flat” in eine netCDF-Datei zu speichern. Und im Beispiel des Matlab-Codes der ersetzt werden soll haben wir ja auch ein dreidimensionales Array, jedenfalls werden da für drei Dimensionen die Start-/Endwerte angegeben.
@derbernd: Nachdem ich jetzt mal in der Matlab-Doku gelesen und im Netz nach Beispielen gesucht habe, würde ich mal ganz frech folgendes behaupten:
Code: Alles auswählen
data = netcdf.getVar(ncid, varid, [0 0 timeStart], [sizex sizey timeDiff+1]);
würde in Python so aussehen:
Code: Alles auswählen
data = dataset.variables[variable_name][:sizex, :sizey, time_start:time_diff + 1]
Falls ``sizex`` und/oder ``sizey`` immer der länge der jeweiligen Dimension entsprechen sollte, braucht man die Werte an der Stelle nicht angeben und kann einfach nur den Doppelpunkt verwenden.
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 13:36
von derbernd
ich habe es jetzt testen können und es läuft! Vielen Dank für die Hilfe.
Eine Frage ist mir dann doch noch eingefallen. Die Reihenfolge der Parameter in der letzten Klammer ist variabel. Die Position (Anordnung) kann aber über den Name der Dimension bestimmt werden. Wie könnte ich dies in python berücksichtigen? Mir würde momentan nur ein if-else-Konstrukt einfallen.
Nachfolgend ein Beispiel
Code: Alles auswählen
data.variables[var_name][time,height,lat,lon]
data.variables[var_name][time,lat,lon,height]
Re: netcdf - Teilarrays lesen
Verfasst: Montag 6. Oktober 2014, 14:58
von BlackJack
@derbernd: Das könnte man mit einem ``if``/``else`` lösen wenn es zwei Möglichkeiten gibt. Falls die Namen immer gleich sind und nur die Reihenfolge variiert könnte man es auch generischer lösen.