Cet article présente xarray, une bibliothèque Python qui prend en charge l'analyse de données multidimensionnelle. Pour plus d'informations, veuillez consulter Information du chef de famille.
Les données de mesure scientifiques sont souvent multidimensionnelles. Par exemple, lors de la mesure de données de séries chronologiques avec des capteurs installés à plusieurs positions, Les données de mesure sont des données bidimensionnelles dans la direction spatiale du canal x la direction temporelle. En outre, lors de l'application d'une transformée de Fourier de courte durée à ces données, elles deviennent des données tridimensionnelles dans la direction du canal spatial x la direction du temps x la direction de la fréquence.
En général, lorsque vous traitez de telles données, je pense que vous utilisez souvent np.ndarray de numpy. Cependant, puisque np.ndarray est une simple matrice (ou tenseur), d'autres informations doivent être mises de côté. Dans l'exemple ci-dessus,
Etc. correspondent à «autres informations» ici.
Par conséquent, par exemple, si vous souhaitez découper une partie d'une certaine plage horaire des données qu'elle contient et l'utiliser. En plus des données découpées, il est nécessaire de découper les données de l'axe des temps en même temps.
Bien sûr, vous pouvez le faire exactement avec un simple np.ndarray, mais Dans un programme compliqué, ces opérations compliquées peuvent être source d'erreurs.
xarray est une bibliothèque qui simplifie ces opérations. (À propos, puisque np.ndarray est utilisé en interne, les performances de calcul haute vitesse de np.ndarray sont à peine sacrifiées.) Il existe des pandas en tant que bibliothèque qui gère des données unidimensionnelles. les pandas ne peuvent pas (facilement) gérer les données multidimensionnelles. xarray est une bibliothèque qui l'interpole.
En plus de ce qui précède,
__str__
est surchargée et vous donnera un aperçu lors de l'impression.Etc.
Au fait,
import numpy as np
import xarray as xr
xr.__version__
'0.9.1'
Il semble qu'il soit courant de l'abréger en «xr».
Il prend principalement en charge deux types de données, xr.DataArray et xr.Dataset.
xr.DataArray
xr.DataArray est les données multidimensionnelles mentionnées ci-dessus.
À l'intérieur, il a un type de dictionnaire ordonné coords
, qui est une paire de valeurs d'axe et d'étiquettes, et un type de dictionnaire ordonné appelé ʻattrs`, qui stocke d'autres informations.
Puisque nous surchargons la méthode __get_item__
, nous pouvons y accéder comme da [i, j] de la même manière que np.ndarray.
Cependant, puisque la valeur de retour est également un objet xr.DataArray, elle hérite des informations d'axe et ainsi de suite.
xr.Dataset Un objet qui contient plusieurs xr.DataArrays. Vous pouvez avoir plusieurs axes et il contiendra des informations sur l'axe auquel chaque donnée correspond.
Il est accessible comme un objet dictionnaire. Par exemple, dans xr.Dataset, qui contient des informations sur la température T et la densité N à l'intérieur. data ['T'] renverra la température T sous la forme xr.DataArray.
C'est un rôle similaire à «DataSeries» dans «pandas». Il a la valeur de données elle-même et les données de l'axe.
data = xr.DataArray(np.random.randn(2, 3))
Ensuite, vous pouvez créer un objet 2x3 xr.DataArray sans informations d'axe.
Vous pouvez afficher le résumé de l'objet créé par la méthode print
.
print(data)
<xarray.DataArray (dim_0: 2, dim_1: 3)>
array([[ 0.32853 , -1.010702, 1.220686],
[ 0.877681, 1.180265, -0.963936]])
Dimensions without coordinates: dim_0, dim_1
Si vous ne spécifiez pas explicitement l'axe comme cette fois, dim_0 et dim_1 seront attribués automatiquement.
Par exemple, considérons le cas où la première dimension d'une certaine donnée «data_np» correspond à la position spatiale x et la seconde dimension correspond au temps t.
#Exemple de données
data_np = np.random.randn(5,4)
x_axis = np.linspace(0.0, 1.0, 5)
t_axis = np.linspace(0.0, 2.0, 4)
data = xr.DataArray(data_np, dims=['x','t'],
coords={'x':x_axis, 't':t_axis},
name='some_measurement')
Etc
dims
, listez (ou tapotez) les étiquettes correspondant à chaque dimension de data_np.coords
l'étiquette de l'axe et les données correspondantes sous forme de dictionnaire.print(data)
<xarray.DataArray 'some_measurement' (x: 5, t: 4)>
array([[ 1.089975, 0.343039, -0.521509, 0.02816 ],
[ 1.117389, 0.589563, -1.030908, -0.023295],
[ 0.403413, -0.157136, -0.175684, -0.743779],
[ 0.814334, 0.164875, -0.489531, -0.335251],
[ 0.009115, 0.294526, 0.693384, -1.046416]])
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Du résumé affiché
<xarray.DataArray 'some_measurement' (x: 5, t: 4)>
Indique que ce DataArray est une matrice 5x4 nommée some_measurement
, avec le premier libellé d'axe de dimension correspondant à" x "et le deuxième libellé d'axe de dimension correspondant à" ".
Aussi,
Coordinates:
Voici une liste de données d'axe.
La liste des axes est accessible par dims
.
De plus, l'ordre affiché ici indique à quel axe de période des données d'origine correspond.
data.dims
('x', 't')
Pour accéder à la valeur de l'axe, prenez le nom de l'étiquette comme argument.
data['x']
<xarray.DataArray 'x' (x: 5)>
array([ 0. , 0.25, 0.5 , 0.75, 1. ])
Coordinates:
* x (x) float64 0.0 0.25 0.5 0.75 1.0
xarray prend en charge plusieurs types d'indexation. Puisqu'il utilise le mécanisme des pandas, il est aussi rapide que les pandas.
data[0,1]
<xarray.DataArray 'some_measurement' ()>
array(0.3430393695918721)
Coordinates:
t float64 0.6667
x float64 0.0
Puisqu'il est de type tableau, il est accessible comme une matrice normale. Les informations d'axe à ce moment-là sont héritées.
Vous pouvez y accéder en spécifiant la position le long des données de l'axe en utilisant la méthode .loc
.
data.loc[0:0.5, :1.0]
<xarray.DataArray 'some_measurement' (x: 3, t: 2)>
array([[ 1.089975, 0.343039],
[ 1.117389, 0.589563],
[ 0.403413, -0.157136]])
Coordinates:
* t (t) float64 0.0 0.6667
* x (x) float64 0.0 0.25 0.5
.loc[0:0.5, :1.0]
Est une opération pour découper des données dans la plage de 0 <x <0,5 le long de l'axe de la première dimension et dans la plage de t <1,0 le long de l'axe de la deuxième dimension.
Utilisez les méthodes .isel
et .sel
pour accéder avec un nom d'étiquette d'axe.
.isel
spécifie l'étiquette de l'axe et son index sous forme d'entier.
data.isel(t=1)
<xarray.DataArray 'some_measurement' (x: 5)>
array([ 0.343039, 0.589563, -0.157136, 0.164875, 0.294526])
Coordinates:
t float64 0.6667
* x (x) float64 0.0 0.25 0.5 0.75 1.0
.sel
spécifie l'étiquette de l'axe et sa valeur d'axe.
data.sel(t=slice(0.5,2.0))
<xarray.DataArray 'some_measurement' (x: 5, t: 3)>
array([[ 0.343039, -0.521509, 0.02816 ],
[ 0.589563, -1.030908, -0.023295],
[-0.157136, -0.175684, -0.743779],
[ 0.164875, -0.489531, -0.335251],
[ 0.294526, 0.693384, -1.046416]])
Coordinates:
* t (t) float64 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Prend en charge de nombreuses opérations de type np.ndarray.
Prend en charge les opérations de base, y compris la diffusion.
data+10
<xarray.DataArray 'some_measurement' (x: 5, t: 4)>
array([[ 11.089975, 10.343039, 9.478491, 10.02816 ],
[ 11.117389, 10.589563, 8.969092, 9.976705],
[ 10.403413, 9.842864, 9.824316, 9.256221],
[ 10.814334, 10.164875, 9.510469, 9.664749],
[ 10.009115, 10.294526, 10.693384, 8.953584]])
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Les calculs élément par élément peuvent hériter de ces informations.
np.sin(data)
<xarray.DataArray 'some_measurement' (x: 5, t: 4)>
array([[ 0.886616, 0.336351, -0.498189, 0.028156],
[ 0.89896 , 0.555998, -0.857766, -0.023293],
[ 0.39256 , -0.15649 , -0.174781, -0.677074],
[ 0.727269, 0.164129, -0.470212, -0.329006],
[ 0.009114, 0.290286, 0.639144, -0.865635]])
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
xr.Dataset
est un objet qui est une collection de plusieurs xr.DataArray
s.
En particulier, vous pouvez indexer et découper xr.DataArray
qui partagent un axe à la fois.
Je pense qu'un instrument de mesure peut produire plusieurs types de signaux,
Il convient au traitement de telles informations ** multidimensionnelles **.
C'est un rôle similaire à «DataFrame» dans «pandas».
Le premier argument est que «data_vars» est semblable à «dict». Passez le nom des données à stocker dans la clé et le taple à deux éléments dans l'élément. Le premier élément du taple passe l'étiquette d'axe correspondant à ces données, et le deuxième élément transmet les données (de type «tableau»).
Passez dict
-like à coords
pour stocker les données d'axe.
Passez l'étiquette d'axe pour la clé et la valeur d'axe pour l'élément.
ds = xr.Dataset({'data1': (['x','t'], np.random.randn(5,4)), 'data2': (['x','t'], np.random.randn(5,4))},
coords={'x': x_axis, 't': t_axis})
ds
<xarray.Dataset>
Dimensions: (t: 4, x: 5)
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Data variables:
data1 (x, t) float64 -1.091 -1.851 0.343 2.077 1.477 0.0009389 1.358 ...
data2 (x, t) float64 0.4852 -0.5463 -0.22 -1.357 -1.416 -0.4929 ...
Pour accéder au contenu, passez le nom de l'étiquette à l'intérieur de []
.
Dans ce cas, la valeur de retour sera «xr.DataArray».
ds['data1']
<xarray.DataArray 'data1' (x: 5, t: 4)>
array([[ -1.091230e+00, -1.851416e+00, 3.429677e-01, 2.077113e+00],
[ 1.476765e+00, 9.389425e-04, 1.358136e+00, -1.627471e+00],
[ -2.007550e-01, 1.008126e-01, 7.177067e-01, 8.893402e-01],
[ -1.813395e-01, -3.407015e-01, -9.673550e-01, 1.135727e+00],
[ 2.423873e-01, -1.198268e+00, 1.650465e+00, -1.923102e-01]])
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Vous pouvez également accéder aux axes par étiquette.
ds['x']
<xarray.DataArray 'x' (x: 5)>
array([ 0. , 0.25, 0.5 , 0.75, 1. ])
Coordinates:
* x (x) float64 0.0 0.25 0.5 0.75 1.0
Utilisez ʻisel` pour l'accès à l'index. Pour accéder au premier élément le long de l'axe des x, spécifiez le nom de l'étiquette de l'axe et son index correspondant, comme suit:
ds.isel(x=1)
<xarray.Dataset>
Dimensions: (t: 4)
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
x float64 0.25
Data variables:
data1 (t) float64 1.477 0.0009389 1.358 -1.627
data2 (t) float64 -1.416 -0.4929 0.4926 -0.7186
Bien sûr, vous pouvez également spécifier plusieurs axes
ds.isel(x=1, t=2)
<xarray.Dataset>
Dimensions: ()
Coordinates:
t float64 1.333
x float64 0.25
Data variables:
data1 float64 1.358
data2 float64 0.4926
Il prend également en charge le tranchage.
ds.isel(x=slice(0,2,1), t=2)
<xarray.Dataset>
Dimensions: (x: 2)
Coordinates:
t float64 1.333
* x (x) float64 0.0 0.25
Data variables:
data1 (x) float64 0.343 1.358
data2 (x) float64 -0.22 0.4926
Utilisez la méthode .sel
pour l'indexation de position.
Comme pour .isel
, spécifiez le nom de l'étiquette de l'axe et cette fois la valeur de l'axe.
ds.sel(x=0.0)
<xarray.Dataset>
Dimensions: (t: 4)
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
x float64 0.0
Data variables:
data1 (t) float64 -1.091 -1.851 0.343 2.077
data2 (t) float64 0.4852 -0.5463 -0.22 -1.357
Par défaut, exactement la même valeur est renvoyée, mais vous pouvez la spécifier avec l'option method
.
Si vous voulez la valeur la plus proche, définissez `méthode = 'plus proche'
# x = 0.Renvoie la valeur avec x la plus proche de 4.
ds.sel(x=0.4, method='nearest')
<xarray.Dataset>
Dimensions: (t: 4)
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
x float64 0.5
Data variables:
data1 (t) float64 -0.2008 0.1008 0.7177 0.8893
data2 (t) float64 -0.03163 0.6942 0.8194 -2.93
Vous pouvez également passer un objet slice.
ds.sel(x=slice(0,0.5))
<xarray.Dataset>
Dimensions: (t: 4, x: 3)
Coordinates:
* t (t) float64 0.0 0.6667 1.333 2.0
* x (x) float64 0.0 0.25 0.5
Data variables:
data1 (x, t) float64 -1.091 -1.851 0.343 2.077 1.477 0.0009389 1.358 ...
data2 (x, t) float64 0.4852 -0.5463 -0.22 -1.357 -1.416 -0.4929 ...
Recommended Posts