Utilisation de l'API Xarray-Python

xarray_logo

Introduction

  • Package python open source
  • Créé par la communauté océan/atmosphère
  • Coeur du projet pangeo

  • Créé pour faciliter le travail sur les données n-dimensions

  • pandas de la donnée n-dimensions
  • Compatible avec numpy, pandas et matplotlib
  • De nombreux packages peuvent utiliser des objets xarray

Fonctionnalités

  • les capacités de Pandas pour de la donnée n-dimensions
  • capable de lire/écrire depuis/vers les formats
    • NetCDF
    • HDF5
    • Zarr
    • openDAP
    • GRIB
  • Intègre la convention netCDF-CF
    • Conversion automatique du temps
    • Interprète les latitudes, longitudes
    • Interprète les unités (grâce au module pint)
  • Chaque variable est associée à:
    • n-dimensions (latitude, longitude, temps, altitude …)
    • Des métadonnées (standard_name, units, comment …)
  • Similaire à pandas
    • Sélection des valeurs par labels possibles (et indices)
    • Resample, groupby …
    • Création des cartes si les données ont lat/lon pour dimensions

Installation

  • avec apt-get sous linux
apt-get install python3-xarray
  • avec pip
pip install xarray[complete]
  • avec conda
conda install -c conda-forge xarray netCDF4 bottleneck

La librairie Xarray

Les objets Xarray

DataArray

Le DataArray correspond à une variable associée à ses dimensions et à ses métadonnées (Attributs). En comparaison de structures de la librairie Pandas dédiée aux séries temporelles, le DataArray est semblable à un objet *Series* de Pandas.

Dataset

Le Dataset correspond à un ensemble de DataArray, c'est la base du netcdf. Dans un Dataset, les DataArray peuvent avoir des dimensions différentes. Des métadonnées peuvent être associées à un DataArray ou à tout le DataSet respectivement à une variable du fichier netCDF ou comme attribut global du netCDF.

Xarray permet de lire du netCDF mais peut-être utilisée comme structures de données sans interaction avec un fichier netcdf. C'est pourquoi la nomenclature peut-être différente du netCDF.

Vous trouverez ci-dessous un exemple de réprésentation d'une struture de données:

xarray_dataset

Création d'un Xarray

On crée les données comme des structures de base de python:

import xarray as xr
import pandas as pd
import numpy as np

np.random.seed(0)
temperature = 15 + 8 * np.random.randn(2, 2, 3)
precipitation = 10 * np.random.rand(2, 2, 3)
lon = [[-99.83, -99.32], [-99.79, -99.23]]
lat = [[42.25, 42.21], [42.63, 42.59]]
time = pd.date_range("2014-09-06", periods=3)
reference_time = pd.Timestamp("2014-09-05")

Ensuite on les affecte à une structure xarray :

ds = xr.Dataset(
    data_vars=dict(
        temperature=(["x", "y", "time"], temperature,{'units':'K'}),
        precipitation=(["x", "y", "time"], precipitation),
    ),
    coords=dict(
        lon=(["x", "y"], lon),
        lat=(["x", "y"], lat),
        time=time,
        reference_time=reference_time,
    ),
    attrs=dict(description="Weather related data."),
)

Si on affiche ds , on obtient la structure suivante :

<xarray.Dataset> Size: 288B
Dimensions:         (x: 2, y: 2, time: 3)
Coordinates:
    lon             (x, y) float64 32B -99.83 -99.32 -99.79 -99.23
    lat             (x, y) float64 32B 42.25 42.21 42.63 42.59
  * time            (time) datetime64[ns] 24B 2014-09-06 2014-09-07 2014-09-08
    reference_time  datetime64[ns] 8B 2014-09-05
Dimensions without coordinates: x, y
Data variables:
    temperature     (x, y, time) float64 96B 29.11 18.2 22.83 ... 16.15 26.63
    precipitation   (x, y, time) float64 96B 5.68 9.256 0.7104 ... 4.615 7.805
Attributes:
    description:  Weather related data.

Ceci ressemble à une structure netcdf avec les données, les coordonnées et les attributes.

Les Fonctions Xarray

  • Import du module
import xarray as xr
  • Ouverture d’un fichier netcdf
data = xr.open_dataset(“fichier.nc”)
  • Ouverture d’un groupe de fichiers
data = xr.open_mfdataset(“*.nc”) # lecture parallèle avec Dask parallel=True
  • Création de variables
data=data.assign(nomVar=Var)
  • Création d’attributs
data = data.assign_attrs(metaDict)  #attributs globaux
data.Var.attrs.update(metaDict)  #attributs d’une variable

Xarray gère automatiquement les units et calendar pour les variables de temps.

  • Création de coordonnées
data=data.assign_coords(nomCoord=var)
  • Ecriture du fichier
data.to_netcdf(“fichierOut.nc”)
  • Resample avec fonction d’aggrégation
data.resample(time=’1D’).interpolate("linear")
  • Tracé de graphisques
data.Var.plot()

TP Xarray

Pour faire le TP, se déplacer dans le répertoir tp/xarray .

cd tp/xarray  # si vous êtes dans votre hom directory
cd xarray # si vous êtes dans le répertoire tp
cd ../xarray # si vous êtes dans un sous-répertoire de tp

Faire avec xarray la même chose qu'avec nco et cdo

import xarray as xar
import matplotlib.pyplot as plt


# Lecture et plot d'une série temporelle #

data = xar.open_dataset('Giens202301Sorted_xarray.nc')
data
data.tmer.plot()
plt.show()

# resample sur 1 jour en appliquant une moyenne puis plot#

data.tmer.resample(time='1D').mean().plot()
plt.show()

######### CAS 2D ##################
# on repart des données du GIEC

data2D= xar.open_dataset('../nco-cdo/tas_histo_one_year.nc')
data2D
data2DFuture= xar.open_dataset('../nco-cdo/tasdeg_rcp85_only.nc')

#create new temperature en °C 
data2D = data2D.assign(tasdeg=data2D.tas-273.15)
# on applique les attributs de tas
data2D.tasdeg.attrs.update(data2D.tas.attrs)
# mais on change l'unité
data2D.tasdeg.attrs.update({'units':'degC'})

# enfin on supprime tas pour ne garder que tasdeg
data2D = data2D.drop_vars('tas')

# on plot l'évolution temporelle à Nantes
data2D.sel(lat=47.218371,lon=358.75,method='nearest').tasdeg.plot()

# on lit les données du GIEC du future
tasDegFuture = data2DFuture.resample(time='1Y').mean()
tasDeg = data2D.resample(time='1Y').mean()

# on essaie une différence
difftas=tasDegFuture.tasdeg-tasDeg.tasdeg
difftas
# mais c'est vide car ce n'est pas les memes dates

# on gruge en repartant des données de base
data=tasDegFuture.tasdeg.values-tasDeg.tasdeg.values

# on crée une nouvelle variable qui contient la différence entre les données futures et actuelles
tasDegFuture=tasDegFuture.assign(tasdiff=(('time','lat','lon'),data))


tasDegFuture.tasdiff.plot()
plt.show()

Transformer les données de Giens en netcdf à partir du csv avec xarray

De même qu'avec l'API netcdf on peut créer un netcdf à partir d'un csv comme réalisé dans le TP précédent.

Le programme ci dessous est équivalent à celui du TP avec l'API Python mais en utilisant xarray et pandas pour lire les csvs. Il lit un fichier de données au format CSV, et le transforme en fichier netCDF.

- Usage :
    - $ genereNetCDF_vxarray.py -n Giens202301Sorted.csv

Liens utiles