2016-05-11 10 views
2

Ich habe eine Reihe von monatlich gerasterten Datensätzen in CSV-Form. Ich möchte sie lesen, ein paar Dimensionen hinzufügen und dann an netcdf schreiben. Ich hatte große Erfahrung mit Xarray (Xray) in der Vergangenheit, so dachte ich, wenn ich für diese Aufgabe verwenden würde.Hinzufügen einer 'konstanten' Dimension zum Xarray-Datensatz

Ich kann sie leicht in eine 2D-Dataarray mit so etwas wie erhalten:

data = np.ones((360,720)) 
lats = np.arange(-89.75, 90, 0.5) * -1 
lngs = np.arange(-179.75, 180, 0.5) 
coords = {'lat': lats, 'lng':lngs} 
da = xr.DataArray(data, coords=coords) 

Aber wenn ich versuche, eine neue Dimension hinzufügen, die Informationen über Zeit vermitteln würde (alle Daten aus dem gleichen Jahr/Monat) Dinge beginnen sauer zu werden.

ich zwei Möglichkeiten habe versucht, diese zu knacken:

1) meine Eingangsdaten erweitern 1 bis mxnx, so etwas wie:

data = np.ones((360,720)) 
lats = np.arange(-89.75, 90, 0.5) * -1 
lngs = np.arange(-179.75, 180, 0.5) 
coords = {'lat': lats, 'lng':lngs} 
data = data[:,:,np.newaxis] 

Dann folge ich die gleichen Schritte wie oben, mit coords aktualisiert eine dritte Dimension enthalten.

lats = np.arange(-89.75, 90, 0.5) * -1 
lngs = np.arange(-179.75, 180, 0.5) 
coords = {'lat': lats, 'lng':lngs} 
coords['time'] = pd.datetime(year, month, day)) 
da = xr.DataArray(data, coords=coords) 
da.to_dataset(name='variable_name') 

Das ist in Ordnung ein Dataarray für die Erstellung - aber wenn ich zu einem Datensatz zu konvertieren versuchen (so kann ich zu netCDF schreiben), habe ich einen Fehler zu bekommen ‚Valueerror: Koordinaten Objekte 1-dimensional sein muss‘

2) Der zweite Ansatz, den ich ausprobiert habe, besteht darin, mein Datenarray in einen Datenframe umzuwandeln, den Index auf ['lat', 'lng', 'time'] zu setzen und dann zu einem Datensatz mit xr.Dataset.from_dataframe() zurückzukehren . Ich habe es versucht - aber es dauert 20+ Minuten, bevor ich den Prozess abbringe.

Weiß jemand, wie ich ein Dataset mit einer monatlichen 'Zeit'-Dimension bekommen kann?

+0

Danke für die Frage. Wenn Sie vollständig reproduzierbare Beispiele veröffentlichen können, ist es ein wenig einfacher, sich darauf einzulassen. Ich werde später einen Blick in beide Richtungen werfen, aber – Maximilian

+0

@Maximilian machte ein paar Änderungen, um Copy/Paste zu unterstützen - ich stelle nicht oft Fragen hier, so würde jede weitere Änderungen/Stiländerungen, die Sie denken, könnte helfen. – badgley

+1

Stephen gab die ideale Antwort, also werde ich nicht versuchen, es zu schlagen. Vielen Dank für die Änderungen, viel besser ... Wenn Sie wirklich eine andere Verfeinerung für die Zukunft wünschen, könnten Ihre Codezeilen in Blöcken sein (beachten Sie, wie Stephan sie unten tut) – Maximilian

Antwort

6

Ihr erstes Beispiel ziemlich nahe ist:

lats = np.arange(-89.75, 90, 0.5) * -1 
lngs = np.arange(-179.75, 180, 0.5) 
coords = {'lat': lats, 'lng': lngs} 
coords['time'] = [datetime.datetime(year, month, day)] 
da = xr.DataArray(data, coords=coords, dims=['lat', 'lng', 'time']) 
da.to_dataset(name='variable_name') 

Sie werden ein paar Änderungen in meiner Version bemerken:

  1. Ich bin in einem ersten für die ‚Zeit‘ vorbei koordinieren statt ein Skalar. Sie müssen eine Liste oder ein 1d-Array übergeben, um eine 1D-Koordinatenvariable zu erhalten, die Sie benötigen, wenn Sie auch "Zeit" als Dimension verwenden. Das ist, was der Fehler ValueError: Coordinate objects must be 1-dimensional versucht, Ihnen zu sagen (übrigens - wenn Sie Ideen haben, wie diese Fehlermeldung hilfreicher zu machen, bin ich ganz Ohr!).
  2. Ich stelle ein dims Argument für den DataArray-Konstruktor. Das Übergeben eines (nicht geordneten) Wörterbuchs ist ein wenig gefährlich, da die Iterationsreihenfolge nicht garantiert ist.
  3. Ich wechselte auch zu datetime.datetime anstelle von pd.datetime. Das Spätere ist einfach ein Alias ​​für Ersteres.

Ein weiterer sinnvoller Ansatz ist concat mit einer Liste von einem Artikel zu benutzen, wenn Sie hinzugefügt haben ‚Zeit‘ als ein Skalar koordinieren, zum Beispiel

lats = np.arange(-89.75, 90, 0.5) * -1 
lngs = np.arange(-179.75, 180, 0.5) 
coords = {'lat': lats, 'lng': lngs, 'time': datetime.datetime(year, month, day)} 
da = xr.DataArray(data, coords=coords, dims=['lat', 'lng']) 
expanded_da = xr.concat([da], 'time') 

Diese Version verallgemeinert schön zu verbinden zusammen Daten aus einer Reihe von Tagen - Sie machen die Liste der DataArrays einfach länger. Meiner Erfahrung nach ist der Grund, warum Sie die zusätzliche Dimension in erster Linie haben wollen, in der Lage zu sein, in der Lage zu sein, entlang es zu begleiten. Länge 1 Dimensionen sind sonst nicht sehr nützlich.

+0

Ich ging mit dem zweiten Ansatz - das erlaubte mir Die Flexibilität, meine lat/lng-Daten als 360x720-Array zu speichern und ein paar zusätzliche Schritte zu entfernen, die ich mir in meiner ursprünglichen Formulierung des Problems gemacht hatte. – badgley

Verwandte Themen