[PYTHON] Datenanalyse mit xarray

Datenanalyse mit xarray

Vorheriger Artikel

Ich werde die oben eingeführte Datenanalyse mit xarray aus praktischerer Sicht vorstellen.

Über den Autor

Seit 2017 ist er Entwicklungsmitglied von pydata xarray. In letzter Zeit bin ich hauptsächlich ein Benutzer, aber ich sende gelegentlich PR für Fehlerbehebungen.

Ich verwende xarray für fast alle Datenanalysen, die ich in meinem Hauptgeschäft durchführe.

Über den beabsichtigten Leser

Es wird davon ausgegangen, dass Sie über Kenntnisse in Numpy verfügen (Sie können Operationen und Operationen mit np.ndarray ausführen).

Struktur dieses Artikels

In diesem Artikel werde ich das xarray-Datenmodell noch einmal vorstellen und dann die grundlegende Operation der Indizierung diskutieren. Man kann mit Sicherheit sagen, dass diese Indizierung die Essenz von xarray ist.

Danach werde ich concat einführen, die umgekehrte Operation der Indizierung.

Auf dieser Grundlage werde ich bei der Betrachtung der tatsächlichen Datenerstellung vorstellen, welche Art von Datenstruktur verwendet werden sollte, um die Analyse mit xarray zu erleichtern.

Ich werde auch ein wenig über das Speichern und Laden von Daten und die Verarbeitung von Speichermangel mit dask sprechen.

Dieser Artikel wurde mit Google Collaboratory verfasst. Jeder kann ausführen und verfolgen, indem er von [hier] kopiert (https://drive.google.com/file/d/1747FtkVJ3KnOszugTGgnmMPIMLPSFg0N/view?usp=sharing).

Xarray-Datenmodell

Überblick

Kurz gesagt, xarray ist ** ein mehrdimensionales Array mit Achsen **. Sie können sich das als eine Kombination aus Numpys nd-Array und pandas 'pd.Series vorstellen.

Sobald Sie sich daran gewöhnt haben, ist dies sehr praktisch, da Sie bei der Datenanalyse nicht an Koordinaten denken müssen.

Andererseits wird oft gesagt, dass die Nutzung ein wenig einzigartig ist und die Lernkosten hoch sind. Dieser Artikel zielt darauf ab, diese Lernkosten so weit wie möglich zu senken.

Es gibt zwei Hauptklassen in xarray. Eines ist xarray.DataArray und das andere ist xarray.Dataset. Ich werde sie vorstellen.

Dies entspricht fast dem in Multarimensional Data Analysis Library xarray beschriebenen Inhalt.

xarray.DataArray

Einführung in xarray.DataArray, ein ** mehrdimensionales Array mit Achsen **. Ich werde später erklären, wie ein Objekt erstellt wird, aber zuerst werde ich die Verwendung der Daten in xarray.tutorial erklären.

import numpy as np
import xarray as xr
data = xr.tutorial.open_dataset('air_temperature')['air']
data
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
[3869000 values with dtype=float32]
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Wobei data eine 3D xr.DataArray-Instanz ist. Die offizielle Abkürzung für xarray lautet "xr".

Wenn Sie "Daten" anzeigen, sehen Sie eine Zusammenfassung wie oben. Das (Zeit: 2920, Lat: 25, Lon: 53) in der oberen Zeile repräsentiert den Dimensionsnamen des gespeicherten Arrays und seine Anzahl von Elementen.

Wie Sie sehen können, behandelt xarray ** jede Dimension mit einem Namen ** (in der offiziellen Dokumentation * label * genannt).

Die erste Achse ist die "Zeit" -Achse, die zweite Achse ist die "Lat" -Achse und die dritte Achse ist die "Lon" -Achse. Wenn Sie es so benennen, müssen Sie sich keine Gedanken über die Reihenfolge der Achsen machen.

Zusätzlich werden jeder Achse Koordinatenwerte hinzugefügt. Eine Liste der Koordinaten wird im Abschnitt "Koordinaten" angezeigt. In diesen Daten haben alle Achsen von "Zeit", "Lat", "Lon" Koordinaten.

Sie können auch andere Daten anhängen. Sie befinden sich im Abschnitt "Attribute".

Wie im Abschnitt Indexierung ausführlich beschrieben, ermöglichen die Koordinatenachsen das intuitive Abrufen von Daten im gewünschten Bereich. Wenn Sie beispielsweise die Daten für den 30. August 2014 möchten,

data.sel(time='2014-08-30')
<xarray.DataArray 'air' (time: 4, lat: 25, lon: 53)>
array([[[270.29   , 270.29   , ..., 258.9    , 259.5    ],
        [273.     , 273.1    , ..., 262.6    , 264.19998],
        ...,
        [299.5    , 298.79   , ..., 299.     , 298.5    ],
        [299.29   , 299.29   , ..., 299.9    , 300.     ]],

       [[269.9    , 270.1    , ..., 258.6    , 259.5    ],
        [273.     , 273.29   , ..., 262.5    , 265.     ],
        ...,
        [299.19998, 298.9    , ..., 298.5    , 298.     ],
        [299.4    , 299.69998, ..., 299.19998, 299.6    ]],

       [[270.4    , 270.69998, ..., 261.29   , 261.9    ],
        [273.     , 273.6    , ..., 266.4    , 268.6    ],
        ...,
        [297.9    , 297.6    , ..., 298.29   , 298.29   ],
        [298.69998, 298.69998, ..., 299.1    , 299.4    ]],

       [[270.     , 270.4    , ..., 266.     , 266.19998],
        [273.     , 273.9    , ..., 268.1    , 269.69998],
        ...,
        [298.5    , 298.29   , ..., 298.69998, 299.     ],
        [299.1    , 299.19998, ..., 299.5    , 299.69998]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2014-08-30 ... 2014-08-30T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Sie können es so machen. Hier wird die Methode ".sel" verwendet, um Daten unter Verwendung der Koordinatenachsen auszuwählen. .sel (time = '2014-08-30') entspricht der Referenzierung der time-Achse und der Auswahl der Daten'2014-08-30'.

Operationen auf DataArray

DataArray ist auch ein mehrdimensionales Array wie np.ndarray, sodass Sie Operationen wie bei np.ndarray ausführen können.

data * 2
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
array([[[482.4    , 485.     , 487.     , ..., 465.59998, 471.     ,
         477.19998],
        [487.59998, 489.     , 489.4    , ..., 465.59998, 470.59998,
         478.59998],
        [500.     , 499.59998, 497.78   , ..., 466.4    , 472.78   ,
         483.4    ],
        ...,
        [593.2    , 592.39996, 592.8    , ..., 590.8    , 590.2    ,
         589.39996],
        [591.8    , 592.39996, 593.58   , ..., 591.8    , 591.8    ,
         590.39996],
        [592.58   , 593.58   , 594.2    , ..., 593.8    , 593.58   ,
         593.2    ]],

       [[484.19998, 485.4    , 486.19998, ..., 464.     , 467.19998,
         471.59998],
        [487.19998, 488.19998, 488.4    , ..., 462.     , 465.     ,
         471.4    ],
        [506.4    , 505.78   , 504.19998, ..., 461.59998, 466.78   ,
         477.     ],
...
        [587.38   , 587.77997, 590.77997, ..., 590.18   , 589.38   ,
         588.58   ],
        [592.58   , 594.38   , 595.18   , ..., 590.58   , 590.18   ,
         588.77997],
        [595.58   , 596.77997, 596.98   , ..., 591.38   , 590.98   ,
         590.38   ]],

       [[490.18   , 488.58   , 486.58   , ..., 483.37997, 482.97998,
         483.58   ],
        [499.78   , 498.58   , 496.78   , ..., 479.18   , 480.58   ,
         483.37997],
        [525.98   , 524.38   , 522.77997, ..., 479.78   , 485.18   ,
         492.58   ],
        ...,
        [587.58   , 587.38   , 590.18   , ..., 590.58   , 590.18   ,
         589.38   ],
        [592.18   , 593.77997, 594.38   , ..., 591.38   , 591.38   ,
         590.38   ],
        [595.38   , 596.18   , 596.18   , ..., 592.98   , 592.38   ,
         591.38   ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00

Wie intuitiv sollte es sein, erfolgt die Multiplikation nur mit den Array-Daten und die Achsdaten bleiben unverändert.

Daten, die außerhalb des Arrays gespeichert werden können

Ich erwähnte, dass Sie neben Array-Daten auch Coordinate halten können. Koordinatendaten können wie folgt kategorisiert werden.

Dimension coordinate

Dies wurde im vorherigen Abschnitt als Koordinate eingeführt. Es hat den gleichen Namen wie der Dimensionsname (time, lon, lat in den Daten im vorherigen Abschnitt).

Non-dimension coordinate

Sie können auch Koordinaten mit Namen halten, die sich von der Dimension unterscheiden. Ich werde erklären, in welchen Situationen es notwendig und zweckmäßig ist, aber grundsätzlich sollte verstanden werden, dass es ** beibehalten, aber nicht berechnet ** wird.

Scalar coordinate

Sie können einen Skalar halten, der eine Koordinatenachse sein kann. Dies ist auch ein häufig verwendeter Datentyp, aber vorerst können Sie ihn als nicht dimensionale Koordinate betrachten, die nicht berechnet, sondern beibehalten wird.

Grundlegende Methode

Es hat die grundlegenden Methoden in np.ndarray gefunden.

Andere,

Sache über Typ

Konvertieren Sie von DataArray nach np.ndarray.

Np.ndarray wird in DataArray gespeichert. (Als Ergänzung können Sie tatsächlich andere mehrdimensionale Arrays als np.ndarray speichern.)

Sie können mit .data auf das Inhaltsarray zugreifen. (Beachten Sie, dass .values jedes Objekt im Inhalt in np.ndarray konvertiert und zurückgibt.)

type(data.data), data.shape
(numpy.ndarray, (2920, 25, 53))

Informationen zur Koordinatenachse extrahieren

Koordinatenachsenobjekte können durch Übergeben des Achsnamens in [] wie in einem Wörterbuch abgerufen werden.

data['lat']
<xarray.DataArray 'lat' (lat: 25)>
array([75. , 72.5, 70. , 67.5, 65. , 62.5, 60. , 57.5, 55. , 52.5, 50. , 47.5,
       45. , 42.5, 40. , 37.5, 35. , 32.5, 30. , 27.5, 25. , 22.5, 20. , 17.5,
       15. ], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
Attributes:
    standard_name:  latitude
    long_name:      Latitude
    units:          degrees_north
    axis:           Y

Das abgerufene Objekt ist auch ein DataArray-Objekt.

xarray.Dataset

Ein Dataset ist ein Objekt, das aus mehreren DataArrays besteht.

data = xr.tutorial.open_dataset('air_temperature')
data['mean_temperature'] = data['air'].mean('time')
data
<xarray.Dataset>
Dimensions:           (lat: 25, lon: 53, time: 2920)
Coordinates:
  * lat               (lat) float32 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lat, lon) float32 241.2 242.5 ... 296.19 295.69
    mean_temperature  (lat, lon) float32 260.37564 260.1826 ... 297.30502
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

In diesem Beispiel enthält "data" zwei DataArrays, "air" und "mean_temperature". Sie sind im Abschnitt "Datenvariablen" aufgeführt.

ist.

Die von Ihnen gehaltenen Datenfelder können Achsen gemeinsam nutzen. Daher ist es möglich, mehrere DataArrays gleichzeitig zu indizieren, wie unten gezeigt.

data.sel(lat=70, method='nearest')
<xarray.Dataset>
Dimensions:           (lon: 53, time: 2920)
Coordinates:
    lat               float32 70.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lon) float32 250.0 249.79999 ... 242.59 246.29
    mean_temperature  (lon) float32 264.7681 264.3271 ... 253.58247 257.71475
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

Das beibehaltene DataArray kann unterschiedliche Dimensionen haben. Ob die Achsen gemeinsam sind oder nicht, wird durch den Namen der Achse bestimmt. Daher ist es nicht möglich, Koordinatenachsen mit demselben Namen zu haben, obwohl sie nicht üblich sind.

Um ein DataArray aus einem Dataset abzurufen, übergeben Sie einfach den Namen des DataArray als Schlüssel, wie in einem Wörterbuch.

da = data['air']
da
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
array([[[241.2    , 242.5    , ..., 235.5    , 238.59999],
        [243.79999, 244.5    , ..., 235.29999, 239.29999],
        ...,
        [295.9    , 296.19998, ..., 295.9    , 295.19998],
        [296.29   , 296.79   , ..., 296.79   , 296.6    ]],

       [[242.09999, 242.7    , ..., 233.59999, 235.79999],
        [243.59999, 244.09999, ..., 232.5    , 235.7    ],
        ...,
        [296.19998, 296.69998, ..., 295.5    , 295.1    ],
        [296.29   , 297.19998, ..., 296.4    , 296.6    ]],

       ...,

       [[245.79   , 244.79   , ..., 243.98999, 244.79   ],
        [249.89   , 249.29   , ..., 242.48999, 244.29   ],
        ...,
        [296.29   , 297.19   , ..., 295.09   , 294.38998],
        [297.79   , 298.38998, ..., 295.49   , 295.19   ]],

       [[245.09   , 244.29   , ..., 241.48999, 241.79   ],
        [249.89   , 249.29   , ..., 240.29   , 241.68999],
        ...,
        [296.09   , 296.88998, ..., 295.69   , 295.19   ],
        [297.69   , 298.09   , ..., 296.19   , 295.69   ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

DataArray-Instanziierung

In diesem Abschnitt wird beschrieben, wie Sie ein DataArray-Objekt erstellen.

Am einfachsten ist es, "np.ndarray" und jeden Achsnamen anzugeben.

xr.DataArray(np.arange(12).reshape(3, 4), dims=['x', 'y'])
<xarray.DataArray (x: 3, y: 4)>
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
Dimensions without coordinates: x, y

Im obigen Beispiel wird ein DataArray mit 3x4-Elementen erstellt. Der Name der ersten Dimension ist "x" und die zweite Dimension ist "y".

Geben Sie das Schlüsselwort "coords" als Wörterbuch an, um die Achsen anzugeben.

xr.DataArray(np.arange(12).reshape(3, 4), dims=['x', 'y'], 
             coords={'x': [0, 1, 2], 'y': [0.1, 0.2, 0.3, 0.4]})
<xarray.DataArray (x: 3, y: 4)>
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
Coordinates:
  * x        (x) int64 0 1 2
  * y        (y) float64 0.1 0.2 0.3 0.4

Um eine Nicht-Dimensionskoordinate einzuschließen, müssen Sie den Achsnamen angeben, von dem sie abhängt. Tippen Sie dazu auf das Argument vom Typ Wörterbuch (rechts neben dem Doppelpunkt). Das erste Element ist der Achsname, von dem es abhängt, und das zweite ist der Array-Body.

xr.DataArray(np.arange(12).reshape(3, 4), dims=['x', 'y'], 
             coords={'x': [0, 1, 2], 'y': [0.1, 0.2, 0.3, 0.4], 
                     'z': ('x', ['a', 'b', 'c'])})
<xarray.DataArray (x: 3, y: 4)>
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
Coordinates:
  * x        (x) int64 0 1 2
  * y        (y) float64 0.1 0.2 0.3 0.4
    z        (x) <U1 'a' 'b' 'c'

Wobei die nicht dimensionale Koordinate "z" auf der "x" -Achse definiert ist.

Übergeben Sie die Skalarkoordinate auch an "Koordinaten".

xr.DataArray(np.arange(12).reshape(3, 4), dims=['x', 'y'], 
             coords={'x': [0, 1, 2], 'y': [0.1, 0.2, 0.3, 0.4], 'scalar': 3})
<xarray.DataArray (x: 3, y: 4)>
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
Coordinates:
  * x        (x) int64 0 1 2
  * y        (y) float64 0.1 0.2 0.3 0.4
    scalar   int64 3

Sie können sehen, dass die Skalarkoordinate zu keiner Dimension gehört.

Zusätzlich zu den Achseninformationen können Sie auch den Namen des Attributs oder DataArray übergeben. Attribute gehen jedoch während des Vorgangs verloren. Daher ist es möglicherweise besser, Dinge, die Sie speichern möchten, sofort in einer Datei abzulegen.

Ich werde dies im Kapitel über die Datenstruktur für die Speicherung erläutern, das später erläutert wird.

Indizierung von ".isel", ".sel", ".interp", ".reindex"

Die Indizierung ist die grundlegendste und wesentlichste Operation. Es ist keine Übertreibung zu sagen, dass die Entwicklung von xarray begonnen hat, es zu vereinfachen.

xarray ermöglicht die positionsbasierte Indizierung und die achsenbasierte Indizierung.

Positionsbasierte Indizierung .isel

Dies ähnelt der Indizierung für gängige Arrays wie np.ndarray. Geben Sie eine Ganzzahl als Argument in Klammern an, z. B. "data [i, j, k]". Das Argument gibt die Position des Elements im ** Array ** an.

da[0, :4, 3]
<xarray.DataArray 'air' (lat: 4)>
array([244.     , 244.2    , 247.5    , 266.69998], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5
    lon      float32 207.5
    time     datetime64[ns] 2013-01-01
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Bei der obigen Notation müssen Sie sich die Position jeder Dimension merken (z. B. ist die Zeitachse die allererste Achse).

Es ist überraschend schwierig, sich bei jeder Analyse daran zu erinnern. Wenn Sie es so schreiben, müssen Sie sich nur den Namen der Achse merken.

da.isel(time=0, lat=slice(0, 4), lon=3)
<xarray.DataArray 'air' (lat: 4)>
array([244.     , 244.2    , 247.5    , 266.69998], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5
    lon      float32 207.5
    time     datetime64[ns] 2013-01-01
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Fügen Sie auf diese Weise den Achsnamen im Schlüsselwortformat in das Argument der Methode .isel () ein und geben Sie den entsprechenden Index nach dem Gleichwert an.

Beachten Sie, dass Sie beim Angeben eines Bereichs explizit Slices (Slice (0, 4)) verwenden müssen.

Koordinatenbasierte Indizierung .sel

Bei der tatsächlichen Datenanalyse wird der interessierende Bereich häufig durch Koordinaten angegeben. Dies kann mit xarray mit der Methode .sel erreicht werden.

da.sel(time='2013-01-01', lat=slice(75, 60))
<xarray.DataArray 'air' (time: 4, lat: 7, lon: 53)>
array([[[241.2    , 242.5    , ..., 235.5    , 238.59999],
        [243.79999, 244.5    , ..., 235.29999, 239.29999],
        ...,
        [272.1    , 270.9    , ..., 275.4    , 274.19998],
        [273.69998, 273.6    , ..., 274.19998, 275.1    ]],

       [[242.09999, 242.7    , ..., 233.59999, 235.79999],
        [243.59999, 244.09999, ..., 232.5    , 235.7    ],
        ...,
        [269.19998, 268.5    , ..., 275.5    , 274.69998],
        [272.1    , 272.69998, ..., 275.79   , 276.19998]],

       [[242.29999, 242.2    , ..., 236.09999, 238.7    ],
        [244.59999, 244.39   , ..., 232.     , 235.7    ],
        ...,
        [273.     , 273.5    , ..., 275.29   , 274.29   ],
        [275.5    , 275.9    , ..., 277.4    , 277.6    ]],

       [[241.89   , 241.79999, ..., 235.5    , 237.59999],
        [246.29999, 245.29999, ..., 231.5    , 234.5    ],
        ...,
        [273.29   , 272.6    , ..., 277.6    , 276.9    ],
        [274.1    , 274.     , ..., 279.1    , 279.9    ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 62.5 60.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2013-01-01T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Geben Sie dem Schlüsselwort wie bei ".isel" den Achsnamen und den gewünschten Koordinatenwert nach dem Gleichwert. Sie können auch das Slice-Objekt verwenden. In diesem Fall können Sie das Argument "Slice" mit einer reellen Zahl versehen.

Es gibt jedoch einige Einschränkungen bei der Methode ".sel".

Wenn Sie ungefähre Koordinatenwerte verwenden möchten

Die .sel Methode hat die Optionen Methode, Toleranz.

Ich denke, die am häufigsten verwendete "Methode" ist "am nächsten". Es wird mit dem nächstgelegenen Koordinatenwert indiziert.

da.sel(lat=76, method='nearest')
<xarray.DataArray 'air' (time: 2920, lon: 53)>
array([[241.2    , 242.5    , 243.5    , ..., 232.79999, 235.5    , 238.59999],
       [242.09999, 242.7    , 243.09999, ..., 232.     , 233.59999, 235.79999],
       [242.29999, 242.2    , 242.29999, ..., 234.29999, 236.09999, 238.7    ],
       ...,
       [243.48999, 242.98999, 242.09   , ..., 244.18999, 244.48999, 244.89   ],
       [245.79   , 244.79   , 243.48999, ..., 243.29   , 243.98999, 244.79   ],
       [245.09   , 244.29   , 243.29   , ..., 241.68999, 241.48999, 241.79   ]],
      dtype=float32)
Coordinates:
    lat      float32 75.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Wenn die achsenbasierte Indizierung nicht funktioniert

Koordinatenachsen haben einen Freiheitsgrad, sodass Sie sie möglicherweise nicht gut indizieren können. Beispielsweise gelten die folgenden Fälle.

Wenn die Koordinatenachsen nicht monoton ansteigen oder monoton abnehmen

Sie können nach dieser Achse mit der Methode "sortby" sortieren, z. B. "da.sortby (" lat ")".

Wenn die Achsen Nan enthalten

Mit der Methode "isnull", die Koordinaten zurückgibt, die nicht "Nan" sind, wie z. B. "da.isel (lat = ~ da [" lat "]. Isnull ())", können Sie ein Array erstellen, das diese Koordinatenwerte überspringt. Masu

Wenn sich die Achsen überlappen

Mit da.isel (lat = np.unique (da ['lat'], return_index = True) [1]) können Sie ein Array erstellen, das den Teil überspringt, der den doppelten Koordinaten entspricht.

Interpolation .interp

Interpolation ist mit der gleichen Syntax wie Indizierung möglich.

da.interp(lat=74)
<xarray.DataArray 'air' (time: 2920, lon: 53)>
array([[242.23999321, 243.29999998, 243.9799988 , ..., 232.79998779,
        235.41999512, 238.87998962],
       [242.69999081, 243.25999451, 243.53999329, ..., 231.60000001,
        233.1599945 , 235.75999145],
       [243.21998903, 243.07599789, 242.97999266, ..., 232.69998783,
        234.45999444, 237.49999702],
       ...,
       [245.72999275, 245.38999009, 244.68999648, ..., 242.74999088,
        243.20999146, 244.00999451],
       [247.42999566, 246.58999336, 245.48999023, ..., 242.4899933 ,
        243.38999027, 244.58999329],
       [247.00999749, 246.28999329, 245.32999587, ..., 240.84999084,
        241.00999144, 241.74999085]])
Coordinates:
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
    lat      int64 74
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Bedingte Indizierung xr.where

Es gibt Zeiten, in denen Sie nur Daten auswählen möchten, die komplexe Bedingungen erfüllen. Zum Beispiel im obigen Beispiel

Oder so.

Wenn das Auswahlergebnis eindimensional ist, beispielsweise wenn ein bestimmter Tag ausgewählt wird, kann es realisiert werden, indem ein eindimensionales Array vom Typ Bool an die Methode ".isel" übergeben wird.

import datetime

#Wähle nur Wochenenden
is_weekend = da['time'].dt.dayofweek.isin([5, 6])
is_weekend
<xarray.DataArray 'dayofweek' (time: 2920)>
array([False, False, False, ..., False, False, False])
Coordinates:
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
#Bool-Typ.Übergeben Sie es an die isel-Methode.
da.isel(time=is_weekend)
<xarray.DataArray 'air' (time: 832, lat: 25, lon: 53)>
array([[[248.59999, 246.89   , ..., 245.7    , 246.7    ],
        [256.69998, 254.59999, ..., 248.     , 250.09999],
        ...,
        [296.69998, 296.     , ..., 295.     , 294.9    ],
        [297.     , 296.9    , ..., 296.79   , 296.69998]],

       [[245.09999, 243.59999, ..., 249.89   , 251.39   ],
        [254.     , 251.79999, ..., 247.79999, 250.89   ],
        ...,
        [296.79   , 296.19998, ..., 294.6    , 294.69998],
        [297.19998, 296.69998, ..., 296.29   , 296.6    ]],

       ...,

       [[242.39   , 241.79999, ..., 247.59999, 247.29999],
        [247.18999, 246.09999, ..., 253.29999, 254.29999],
        ...,
        [294.79   , 295.29   , ..., 297.69998, 297.6    ],
        [296.38998, 297.19998, ..., 298.19998, 298.29   ]],

       [[249.18999, 248.     , ..., 244.09999, 242.5    ],
        [254.5    , 253.     , ..., 251.     , 250.59999],
        ...,
        [294.88998, 295.19998, ..., 298.     , 297.29   ],
        [296.1    , 296.88998, ..., 298.5    , 298.29   ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-05 ... 2014-12-28T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Wenn Sie eine Auswahl basierend auf den Daten eines mehrdimensionalen Arrays treffen möchten, können Sie die Form des Arrays nach der Auswahl nicht definieren. Daher empfiehlt es sich, die nicht ausgewählten Elemente durch Nan zu ersetzen. In diesem Fall können Sie die Funktion "where" verwenden.

da.where(da > 270)
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
array([[[      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        ...,
        [296.6    , 296.19998, 296.4    , ..., 295.4    , 295.1    ,
         294.69998],
        [295.9    , 296.19998, 296.79   , ..., 295.9    , 295.9    ,
         295.19998],
        [296.29   , 296.79   , 297.1    , ..., 296.9    , 296.79   ,
         296.6    ]],

       [[      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
...
        [293.69   , 293.88998, 295.38998, ..., 295.09   , 294.69   ,
         294.29   ],
        [296.29   , 297.19   , 297.59   , ..., 295.29   , 295.09   ,
         294.38998],
        [297.79   , 298.38998, 298.49   , ..., 295.69   , 295.49   ,
         295.19   ]],

       [[      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        [      nan,       nan,       nan, ...,       nan,       nan,
               nan],
        ...,
        [293.79   , 293.69   , 295.09   , ..., 295.29   , 295.09   ,
         294.69   ],
        [296.09   , 296.88998, 297.19   , ..., 295.69   , 295.69   ,
         295.19   ],
        [297.69   , 298.09   , 298.09   , ..., 296.49   , 296.19   ,
         295.69   ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Hier ersetzen wir die Elemente, die nicht für "da> 270" gelten, durch "np.nan".

Indizierung weiterentwickeln

Bisher haben wir die grundlegende Indizierung eingeführt, aber xarray ermöglicht auch die erweiterte Indizierung.

Wie in dieser Abbildung gezeigt, können Sie ein anderes Array aus dem mehrdimensionalen Array ausschneiden. Im offiziellen Dokument heißt es Erweiterte Indizierung.

image.png

Definieren Sie dazu das als Argument übergebene Array als DataArray. Legen Sie zu diesem Zeitpunkt die Abmessungen dieser Arrays auf die Abmessungen des neu erstellten Arrays fest.

Gemäß der obigen Abbildung ist die neue Dimension "z". Definieren Sie also ein DataArray auf "z".

lon_new = xr.DataArray([60, 61, 62], dims=['z'], coords={'z': ['a', 'b', 'c']})
lat_new = xr.DataArray([16, 46, 76], dims=['z'], coords={'z': ['a', 'b', 'c']})

Wenn Sie diese als Argumente an die Methode ".sel" übergeben, ist "(lon, lat)" [(60, 16), (61, 46), (62, 76)] "(am nächsten). Wird wählen.

da.sel(lon=lon_new, lat=lat_new, method='nearest')
<xarray.DataArray 'air' (time: 2920, z: 3)>
array([[296.29   , 280.     , 241.2    ],
       [296.29   , 279.19998, 242.09999],
       [296.4    , 278.6    , 242.29999],
       ...,
       [298.19   , 279.99   , 243.48999],
       [297.79   , 279.69   , 245.79   ],
       [297.69   , 279.79   , 245.09   ]], dtype=float32)
Coordinates:
    lat      (z) float32 15.0 45.0 75.0
    lon      (z) float32 200.0 200.0 200.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
  * z        (z) <U1 'a' 'b' 'c'
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Sie können sehen, dass die neu erhaltene Sequenz nicht mehr von den "lon" -, "lat" -Achsen abhängt, sondern vom "z".

Ein ähnliches Verfahren kann auch für die Interpolation verwendet werden.

da.interp(lon=lon_new, lat=lat_new)
<xarray.DataArray 'air' (time: 2920, z: 3)>
array([[nan, nan, nan],
       [nan, nan, nan],
       [nan, nan, nan],
       ...,
       [nan, nan, nan],
       [nan, nan, nan],
       [nan, nan, nan]])
Coordinates:
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
    lon      (z) int64 60 61 62
    lat      (z) int64 16 46 76
  * z        (z) <U1 'a' 'b' 'c'
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Kombinieren Sie die Daten "xr.concat"

Oft möchten Sie mehrere Röntgenobjekte kombinieren. Zum Beispiel, wenn Sie experimentelle Daten und Simulationsdaten analysieren möchten, die mit verschiedenen Parametern zusammen erhalten wurden.

Dies entspricht "np.concatenate", "np.stack". Ich denke, es ist leicht zu verstehen, wenn Sie es als die umgekehrte Operation der Indizierung betrachten.

Die Syntax lautet

xr.concat([data1, data2, ..., ], dim='dim')

ist. Übergeben Sie mehrere DataArrays (oder Datasets) als erstes Argument. Das zweite Argument ist die Richtung des Joins. Abhängig von der Verbindungsrichtung kann es in Verkettungs- und Stapeloperationen unterteilt werden.

Geben Sie eine vorhandene Achse an (verkettetes Verhalten)

Die Grundoperation der Funktion "xr.concat" besteht darin, mehrere DataArrays entlang der vorhandenen Achse zu verbinden.

Zum Beispiel die folgenden zwei DataArray

da0 = da.isel(time=slice(0, 10))
da1 = da.isel(time=slice(10, None))
da0
<xarray.DataArray 'air' (time: 10, lat: 25, lon: 53)>
array([[[241.2    , 242.5    , ..., 235.5    , 238.59999],
        [243.79999, 244.5    , ..., 235.29999, 239.29999],
        ...,
        [295.9    , 296.19998, ..., 295.9    , 295.19998],
        [296.29   , 296.79   , ..., 296.79   , 296.6    ]],

       [[242.09999, 242.7    , ..., 233.59999, 235.79999],
        [243.59999, 244.09999, ..., 232.5    , 235.7    ],
        ...,
        [296.19998, 296.69998, ..., 295.5    , 295.1    ],
        [296.29   , 297.19998, ..., 296.4    , 296.6    ]],

       ...,

       [[244.79999, 244.39   , ..., 242.7    , 244.79999],
        [246.7    , 247.09999, ..., 237.79999, 240.2    ],
        ...,
        [297.79   , 297.19998, ..., 296.4    , 295.29   ],
        [297.9    , 297.69998, ..., 297.19998, 297.     ]],

       [[243.89   , 243.79999, ..., 240.29999, 242.59999],
        [245.5    , 245.79999, ..., 236.59999, 239.     ],
        ...,
        [297.6    , 297.     , ..., 295.6    , 295.     ],
        [298.1    , 297.69998, ..., 296.79   , 297.1    ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2013-01-03T06:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Sie können die Originaldaten wiederherstellen, indem Sie eine Verbindung in Richtung "Zeit" herstellen.

xr.concat([da0, da1], dim='time')
<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
array([[[241.2    , 242.5    , 243.5    , ..., 232.79999, 235.5    ,
         238.59999],
        [243.79999, 244.5    , 244.7    , ..., 232.79999, 235.29999,
         239.29999],
        [250.     , 249.79999, 248.89   , ..., 233.2    , 236.39   ,
         241.7    ],
        ...,
        [296.6    , 296.19998, 296.4    , ..., 295.4    , 295.1    ,
         294.69998],
        [295.9    , 296.19998, 296.79   , ..., 295.9    , 295.9    ,
         295.19998],
        [296.29   , 296.79   , 297.1    , ..., 296.9    , 296.79   ,
         296.6    ]],

       [[242.09999, 242.7    , 243.09999, ..., 232.     , 233.59999,
         235.79999],
        [243.59999, 244.09999, 244.2    , ..., 231.     , 232.5    ,
         235.7    ],
        [253.2    , 252.89   , 252.09999, ..., 230.79999, 233.39   ,
         238.5    ],
...
        [293.69   , 293.88998, 295.38998, ..., 295.09   , 294.69   ,
         294.29   ],
        [296.29   , 297.19   , 297.59   , ..., 295.29   , 295.09   ,
         294.38998],
        [297.79   , 298.38998, 298.49   , ..., 295.69   , 295.49   ,
         295.19   ]],

       [[245.09   , 244.29   , 243.29   , ..., 241.68999, 241.48999,
         241.79   ],
        [249.89   , 249.29   , 248.39   , ..., 239.59   , 240.29   ,
         241.68999],
        [262.99   , 262.19   , 261.38998, ..., 239.89   , 242.59   ,
         246.29   ],
        ...,
        [293.79   , 293.69   , 295.09   , ..., 295.29   , 295.09   ,
         294.69   ],
        [296.09   , 296.88998, 297.19   , ..., 295.69   , 295.69   ,
         295.19   ],
        [297.69   , 298.09   , 298.09   , ..., 296.49   , 296.19   ,
         295.69   ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Beachten Sie auch, dass die Zeitachse ebenfalls wiederhergestellt wurde.

Geben Sie eine neue Achse an (Stapeloperation)

Angenommen, Sie haben zwei DataArrays wie folgt:

da0 = da.isel(time=0)
da1 = da.isel(time=1)
da0
<xarray.DataArray 'air' (lat: 25, lon: 53)>
array([[241.2    , 242.5    , 243.5    , ..., 232.79999, 235.5    , 238.59999],
       [243.79999, 244.5    , 244.7    , ..., 232.79999, 235.29999, 239.29999],
       [250.     , 249.79999, 248.89   , ..., 233.2    , 236.39   , 241.7    ],
       ...,
       [296.6    , 296.19998, 296.4    , ..., 295.4    , 295.1    , 294.69998],
       [295.9    , 296.19998, 296.79   , ..., 295.9    , 295.9    , 295.19998],
       [296.29   , 296.79   , 297.1    , ..., 296.9    , 296.79   , 296.6    ]],
      dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
    time     datetime64[ns] 2013-01-01
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

So kombinieren Sie dies in Richtung der Zeitachse:

xr.concat([da0, da1], dim='time')
<xarray.DataArray 'air' (time: 2, lat: 25, lon: 53)>
array([[[241.2    , 242.5    , 243.5    , ..., 232.79999, 235.5    ,
         238.59999],
        [243.79999, 244.5    , 244.7    , ..., 232.79999, 235.29999,
         239.29999],
        [250.     , 249.79999, 248.89   , ..., 233.2    , 236.39   ,
         241.7    ],
        ...,
        [296.6    , 296.19998, 296.4    , ..., 295.4    , 295.1    ,
         294.69998],
        [295.9    , 296.19998, 296.79   , ..., 295.9    , 295.9    ,
         295.19998],
        [296.29   , 296.79   , 297.1    , ..., 296.9    , 296.79   ,
         296.6    ]],

       [[242.09999, 242.7    , 243.09999, ..., 232.     , 233.59999,
         235.79999],
        [243.59999, 244.09999, 244.2    , ..., 231.     , 232.5    ,
         235.7    ],
        [253.2    , 252.89   , 252.09999, ..., 230.79999, 233.39   ,
         238.5    ],
        ...,
        [296.4    , 295.9    , 296.19998, ..., 295.4    , 295.1    ,
         294.79   ],
        [296.19998, 296.69998, 296.79   , ..., 295.6    , 295.5    ,
         295.1    ],
        [296.29   , 297.19998, 297.4    , ..., 296.4    , 296.4    ,
         296.6    ]]], dtype=float32)
Coordinates:
  * lat      (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 2013-01-01T06:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Auf diese Weise verbinden Sie eine Skalarkoordinate mit der Bezeichnung "Zeit" in "da0", "da1", in diese Richtung. Sie können die Zeitachse zu einer neuen Dimensionskoordinate machen (indem Sie im Schlüsselwort "dim" einen Namen angeben, z. B. "dim =" time ").

Alternativ können Sie eine neue Koordinatenachse für diesen Namen erstellen, indem Sie dem Schlüsselwort "dim" ein DataArray geben.

Datei IO

Ein weiterer Vorteil von xarray besteht darin, dass Daten wie DataArray und Dataset konsistent und in sich geschlossen gespeichert werden können. Es unterstützt mehrere Dateiformate, aber die am einfachsten zu verwendende ist wahrscheinlich netCDF.

Wikipedia hat auch eine Erklärung.

NetCDF ist ein modellunabhängiges Binärformat des Computers (modellunabhängig), kann Daten als Array lesen und schreiben (Array-orientiert) und kann zusätzlich zu den Daten Erklärungen zu den Daten speichern (selbstbeschreibend). ). NetCDF ist ein internationaler Standard im Open Geospatial Consortium, einem internationalen Konsortium, das offene geografische Informationsstandards entwickelt.

Derzeit werden die Versionen 3 und 4 gewartet, es ist jedoch sicherer, Version 4 zu verwenden. Version 4 entspricht dem HDF5-Standard, sodass auch ein normaler HDF5-Leser den Inhalt lesen kann.

Die offizielle Erweiterung lautet ".nc".

Speichern und Laden von Dateien im netCDF-Format

Das Paket "netcdf4" ist erforderlich, um im netCDF-Format zu speichern.

pip install netcdf4

Oder

conda install netcdf4

Lassen Sie es uns ausführen und auf Ihrem System installieren.

Führen Sie die Methode .to_netcdf aus, um das xarray-Objekt im netCDF-Format zu speichern.

data.to_netcdf('test.nc')
/home/keisukefujii/miniconda3/envs/xarray/lib/python3.7/site-packages/ipykernel_launcher.py:1: SerializationWarning: saving variable air with floating point data as an integer dtype without any _FillValue to use for NaNs
  """Entry point for launching an IPython kernel.

Sie sollten jetzt test.nc in Ihrem aktuellen Pfad gespeichert haben.

Um die gespeicherte Datei zu laden, führen Sie "xr.load_dataset" aus.

xr.load_dataset('test.nc')
<xarray.Dataset>
Dimensions:           (lat: 25, lon: 53, time: 2920)
Coordinates:
  * lat               (lat) float32 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lat, lon) float32 241.2 242.5 ... 296.19 295.69
    mean_temperature  (lat, lon) float32 260.37564 260.1826 ... 297.30502
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

Wie Sie sehen können, werden nicht nur der Teil des Arrays, sondern auch der Achsname, die Koordinatenwerte und andere Informationen in "Attributen" gespeichert.

Ein Hinweis zu scipy.io.netcdf

Das xarray .to_netcdf verwendet standardmäßig die Bibliothek netcdf4, verwendet jedoch scipy.io.netcdf, wenn es nicht auf Ihrem System installiert ist. Scipy.io.netcdf unterstützt jedoch Version 3, die mit Version 4 nicht kompatibel ist und verwirrend sein kann.

Vergessen Sie nicht, "netcdf4" auf Ihrem System zu installieren. Alternativ können Sie das zu verwendende Paket explizit angeben, z. B. ".to_netcdf (" test.nc ", engine =" netcdf4 ")".

Nicht genügend Speicher-Array

Dateien im NetCDF-Format können zufällig gelesen werden. Wenn Sie daher nur die Daten eines bestimmten Teils der Datei verwenden möchten, ist es daher effizient, alle Daten bei Bedarf zu lesen, anstatt sie zuerst von der Festplatte zu lesen. Insbesondere bei Dateien, die zu groß sind, um im Speicher gespeichert zu werden, ist eine solche Verarbeitung unerlässlich. Dies wird als Out-of-Memory-Verarbeitung bezeichnet.

Die Verarbeitung von Speichermangel in xarray wird gestern als ziemlich wichtig eingestuft, und verschiedene Implementierungen sind im Gange. Ich werde die Details in einem anderen Artikel vorstellen und hier nur die grundlegendsten Inhalte erwähnen.

Die Verarbeitung zu wenig Speicher wird ausgeführt, indem beim Laden "open_dataset" anstelle von "load_dataset" ausgeführt wird.

unloaded_data = xr.open_dataset('test.nc')
unloaded_data
<xarray.Dataset>
Dimensions:           (lat: 25, lon: 53, time: 2920)
Coordinates:
  * lat               (lat) float32 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lat, lon) float32 ...
    mean_temperature  (lat, lon) float32 ...
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

Wenn Sie sich zum Beispiel "Datenvariablen" ansehen, können Sie sehen, dass in "Luft" keine Nummer ist, sondern nur "...".

Dies zeigt an, dass keine Daten gelesen wurden. Da jedoch die Koordinatenachsen immer gelesen werden, kann die obige Indizierungsarbeit so ausgeführt werden, wie sie ist.

unloaded_data['air'].sel(lat=60, method='nearest')
<xarray.DataArray 'air' (time: 2920, lon: 53)>
[154760 values with dtype=float32]
Coordinates:
    lat      float32 60.0
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
    long_name:     4xDaily Air temperature at sigma level 995
    units:         degK
    precision:     2
    GRIB_id:       11
    GRIB_name:     TMP
    var_desc:      Air temperature
    dataset:       NMC Reanalysis
    level_desc:    Surface
    statistic:     Individual Obs
    parent_stat:   Other
    actual_range:  [185.16 322.1 ]

Wenn ich eine Variable auswähle oder indiziere, wird sie immer noch nicht geladen. Es wird zum ersten Mal in den Speicher geladen, wenn es berechnet wird oder wenn ".data" oder ".values" aufgerufen wird.

Sie können auch die Methode .compute () verwenden, um sie explizit zu laden.

unloaded_data.compute()
<xarray.Dataset>
Dimensions:           (lat: 25, lon: 53, time: 2920)
Coordinates:
  * lat               (lat) float32 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lat, lon) float32 241.2 242.5 ... 296.19 295.69
    mean_temperature  (lat, lon) float32 260.37564 260.1826 ... 297.30502
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

Hinweis

open_dataset, open_dataarray sperrt die Datei für das zukünftige Lesen. Wenn Sie eine Datei mit demselben Namen in einem anderen Programm berühren, tritt daher ein Fehler auf.

Betrachten Sie beispielsweise den Fall, in dem das Ergebnis einer zeitaufwändigen Berechnung jedes Mal als ".nc" -Datei ausgegeben wird. Wenn Sie den Fortschritt sehen und mit "open_dataset" öffnen möchten, schlagen alle nachfolgenden Versuche, in diese Datei zu schreiben, fehl. Es ist besser, wenn es nur fehlschlägt und stoppt, aber es scheint, dass es häufig vorhandene Daten zerstört. Dieser Prozess mit nicht genügend Arbeitsspeicher sollte mit Vorsicht angewendet werden.

Mit der Anweisung "with" können Sie sicherstellen, dass die Datei geschlossen und entsperrt wird, wie unten gezeigt.

with xr.open_dataset('test.nc') as f:
  print(f)
<xarray.Dataset>
Dimensions:           (lat: 25, lon: 53, time: 2920)
Coordinates:
  * lat               (lat) float32 75.0 72.5 70.0 67.5 ... 22.5 20.0 17.5 15.0
  * lon               (lon) float32 200.0 202.5 205.0 ... 325.0 327.5 330.0
  * time              (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Data variables:
    air               (time, lat, lon) float32 ...
    mean_temperature  (lat, lon) float32 ...
Attributes:
    Conventions:  COARDS
    title:        4x daily NMC reanalysis (1948)
    description:  Data is from NMC initialized reanalysis\n(4x/day).  These a...
    platform:     Model
    references:   http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reanaly...

Empfohlene Datenstruktur

Wie oben erwähnt, können Sie die Daten mit xarray reibungslos analysieren, wenn Sie die Daten im netcdf-Format speichern. Wenn Sie Daten für Experimente oder Simulationen erstellen, empfiehlt es sich, eine Datenstruktur zu erstellen, die die nachfolgende Analyse berücksichtigt, und diese im netcdf-Format einschließlich dieser zu speichern.

Es wird empfohlen, die folgenden Daten unterdrückt zu halten.

Im Falle eines Experiments denke ich, dass es mit der folgenden Struktur gespeichert werden sollte.

from datetime import datetime
#Nehmen wir an, dass dies Bilddaten sind, die mit einer Kamera aufgenommen wurden.
raw_data = np.arange(512 * 2048).reshape(512, 2048)
#Die x- und y-Achsenkoordinaten des Bildes.
x = np.arange(512)
y = np.arange(2048)

#Positionsdaten für jedes Pixel des Bildes
r = 300.0
X = r * np.cos(x / 512)[:, np.newaxis] + r * np.sin(y / 2048)
Y = r * np.sin(x / 512)[:, np.newaxis] - r * np.cos(y / 2048)

#Im Experiment verwendete Parameter
p0 = 3.0
p1 = 'normal'

#Experimentierzeit
now = datetime.now()

data = xr.DataArray(
    raw_data, dims=['x', 'y'],
    coords={'x': x, 'y': y, 
            'X': (('x', 'y'), X),
            'Y': (('x', 'y'), Y),
            'p0': p0, 'p1': p1,
            'datetime': now},
    attrs={'camera type': 'flash 4', 
           'about': 'Example of the recommended data structure.'})
data
<xarray.DataArray (x: 512, y: 2048)>
array([[      0,       1,       2, ...,    2045,    2046,    2047],
       [   2048,    2049,    2050, ...,    4093,    4094,    4095],
       [   4096,    4097,    4098, ...,    6141,    6142,    6143],
       ...,
       [1042432, 1042433, 1042434, ..., 1044477, 1044478, 1044479],
       [1044480, 1044481, 1044482, ..., 1046525, 1046526, 1046527],
       [1046528, 1046529, 1046530, ..., 1048573, 1048574, 1048575]])
Coordinates:
  * x         (x) int64 0 1 2 3 4 5 6 7 8 ... 504 505 506 507 508 509 510 511
  * y         (y) int64 0 1 2 3 4 5 6 7 ... 2041 2042 2043 2044 2045 2046 2047
    X         (x, y) float64 300.0 300.1 300.3 300.4 ... 414.7 414.8 414.9 414.9
    Y         (x, y) float64 -300.0 -300.0 -300.0 -300.0 ... 89.66 89.79 89.91
    p0        float64 3.0
    p1        <U6 'normal'
    datetime  datetime64[ns] 2020-11-13T03:31:56.219372
Attributes:
    camera type:  flash 4
    about:        Example of the recommended data structure.

Durch das Sammeln von Dingen, die sich während des Experiments ändern können, in Skalarkoordinaten ist es später einfacher zu analysieren, wenn Sie die Abhängigkeiten von ihnen kennen möchten.

Andere nützliche Funktionen / Methoden

Reduction .sum, .mean, etc

Reduktionsprozesse wie "np.sum" und "np.mean" werden als Methoden bereitgestellt. Mit np.sum können Sie beispielsweise angeben, in welche Achsenrichtung hinzugefügt werden soll. In ähnlicher Weise können Sie mit xarray eine Achse als Achsnamen angeben.

data = xr.tutorial.open_dataset('air_temperature')['air']

data.sum('lat')
<xarray.DataArray 'air' (time: 2920, lon: 53)>
array([[6984.9497, 6991.6606, 6991.5303, ..., 6998.77  , 7007.8804,
        7016.5605],
       [6976.4307, 6988.45  , 6993.2407, ..., 6994.3906, 7006.7505,
        7019.941 ],
       [6975.2603, 6982.02  , 6988.77  , ..., 6992.0503, 7004.9404,
        7020.3506],
       ...,
       [6990.7505, 6998.3496, 7013.3496, ..., 6995.05  , 7008.6504,
        7019.4497],
       [6984.95  , 6991.6504, 7007.949 , ..., 6994.15  , 7008.55  ,
        7020.8506],
       [6981.75  , 6983.85  , 6997.0503, ..., 6985.6494, 6999.2495,
        7012.0493]], dtype=float32)
Coordinates:
  * lon      (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
  * time     (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00

Wenn Sie auf diese Weise in einer bestimmten axialen Richtung addieren, gibt es in dieser Richtung keine Koordinatenachsen. Die anderen Achsen bleiben erhalten.

Bei der Ausführung von ".sum" usw. wird "np.nansum" standardmäßig anstelle von "np.sum" aufgerufen, und das Überspringen der Berechnung "Nan" wird durchgeführt. Wenn Sie "Nan" nicht überspringen möchten (wenn Sie "np.sum" anstelle von "np.nansum" verwenden möchten), müssen Sie "skipna = False" angeben.

Zeichnung .plot

DataArray verfügt über eine Plot-Methode, mit der sich der Inhalt der Daten leicht visualisieren lässt.

data.sel(time='2014-08-30 08:00', method='nearest').plot()
<matplotlib.collections.QuadMesh at 0x7f9a98557310>

output_102_1.png

Es ist vielleicht besser, es als einfach zu betrachten, als ein endgültiges Diagramm des Papiers / Berichts zu erstellen, aber um die Daten mit Jupyter, Ipython usw. zu visualisieren und zu verstehen und mit der Analyse fortzufahren. Sehr bequem zu bedienen.

Recommended Posts

Datenanalyse mit xarray
Mehrdimensionale Datenanalysebibliothek xarray
Datenanalyse mit Python-Pandas
Empfehlung zur Datenanalyse mit MessagePack
Mehrdimensionale Datenanalysebibliothek xarray Teil 2
Datenanalyse Titanic 2
Datenanalyse Python
Datenanalyse Titanic 1
Datenanalyse Titanic 3
Erstellen einer Datenanalyseanwendung mit Streamlit
Datenanalyse mit Python 2
Datenanalyse Übersicht Python
Medianfilter mit Röntgenstrahl (Medianfilter)
Datenbereinigung 2 Datenbereinigung mit DataFrame
Datenbereinigung mit Python
Python-Datenanalysevorlage
Orthologe Analyse mit OrthoFinder
Datenanalyse mit Python
[Python] [Word] [python-docx] Einfache Analyse von Diff-Daten mit Python
Big-Data-Analyse mit dem Datenflusskontroll-Framework Luigi
[Technisches Buch] Einführung in die Datenanalyse mit Python -1 Kapitel Einführung-
Mein Python-Datenanalyse-Container
Python für die Datenanalyse Kapitel 4
Japanische morphologische Analyse mit Janome
Wählen Sie Features mit Textdaten aus
[Python] Hinweise zur Datenanalyse
Lernnotizen zur Python-Datenanalyse
Datenvisualisierungsmethode mit Matplotlib (1)
Datenvisualisierungsmethode mit Matplotlib (2)
Python für die Datenanalyse Kapitel 2
Wrap-Analyse Teil1 (Datenaufbereitung)
Tipps und Vorsichtsmaßnahmen bei der Datenanalyse
Python für die Datenanalyse Kapitel 3
Twitter-Daten analysieren | Trendanalyse
[Einführung] Künstliche Satellitendatenanalyse mit Python (Google Colab-Umgebung)
Ich habe versucht, scRNA-seq-Daten mithilfe der topologischen Datenanalyse (TDA) zu analysieren.
Erste Satellitendatenanalyse von Tellus
Abrufen von Salesforce-Daten mithilfe der REST-API
Datenerfassung mit Python Googlemap API
Vorsichtsmaßnahmen bei der Verwendung der TextBlob-Merkmalsanalyse
Datenvisualisierungsmethode mit Matplotlib (+ Pandas) (5)
Python: Zeitreihenanalyse: Vorverarbeitung von Zeitreihendaten
Analysieren Sie Daten im CSV-Format mit SQL
Gesichtserkennung mit Hauptkomponentenanalyse
Abrufen von Amazon-Daten mit Keep API # 1 Abrufen von Daten
Datenvisualisierungsmethode mit Matplotlib (+ Pandas) (3)
Vorverarbeitungsvorlage für die Datenanalyse (Python)
Datenerfassungsnotiz mit der Backlog-API
November 2020 Version Datenanalyse Test bestanden Erfahrung
Datenanalyse zur Verbesserung von POG 3 ~ Regressionsanalyse ~
Japanische Analyseverarbeitung mit Janome Teil1
Binarisierung von Bildern mittels linearer Diskriminanzanalyse
Zeitreihenanalyse 3 Vorverarbeitung von Zeitreihendaten
Holen Sie sich Daten von Twitter mit Tweepy
Datenanalyse beginnend mit Python (Datenvisualisierung 1)
Datenvisualisierungsmethode mit Matplotlib (+ Pandas) (4)
Datenanalyse beginnend mit Python (Datenvisualisierung 2)
Empfehlungs-Tutorial mit Assoziationsanalyse (Konzept)
Datenverarbeitung 2 Analyse verschiedener Datenformate