5 votes

Aplatir/rabattre/réduire un xr.DataArray (Xarray) tridimensionnel en 2 dimensions le long d'un axe ?

J'ai un ensemble de données dans lequel je stocke des répliques pour différentes classes/sous-types (je ne sais pas comment l'appeler), puis des attributs pour chacune d'elles. Essentiellement, il y a 5 sous-types/classes, 4 répliques pour chaque sous-type/classe, et 100 attributs qui sont mesurés.

Existe-t-il une méthode comme np.ravel ou np.flatten qui peut fusionner 2 dimensions en utilisant Xarray ?

Dans ce cas, je veux fusionner les dims subtype y replicates J'ai donc un tableau 2D (ou pd.DataFrame con attributes vs. subtype/replicates .

Il n'est pas nécessaire que le format soit "coord_1 | coord_2" ou autre. Il serait utile de conserver les noms originaux des coordonnées. Il y a peut-être quelque chose comme groupby qui pourrait faire ça ? Groupby m'a toujours dérouté, donc si c'est quelque chose de natif à xarray Ce serait génial.

import xarray as xr
import numpy as np

# Set up xr.DataArray
dims = (5,4,100)
DA_data = xr.DataArray(np.random.random(dims), dims=["subtype","replicates","attributes"])
DA_data.coords["subtype"] = ["subtype_%d"%_ for _ in range(dims[0])]
DA_data.coords["replicates"] = ["rep_%d"%_ for _ in range(dims[1])]
DA_data.coords["attributes"] = ["attr_%d"%_ for _ in range(dims[2])]

# DA_data.coords
# Coordinates:
#   * subtype     (subtype) <U9 'subtype_0' 'subtype_1' 'subtype_2' ...
#   * replicates  (replicates) <U5 'rep_0' 'rep_1' 'rep_2' 'rep_3'
#   * attributes  (attributes) <U7 'attr_0' 'attr_1' 'attr_2' 'attr_3' ...
# DA_data.dims
# ('subtype', 'replicates', 'attributes')

# Naive way to collapse the replicate dimension into the subtype dimension
desired_columns = list()
for subtype in DA_data.coords["subtype"]:
    for replicate in DA_data.coords["replicates"]:
        desired_columns.append(str(subtype.values) + "|" + str(replicate.values))
desired_columns
# ['subtype_0|rep_0',
#  'subtype_0|rep_1',
#  'subtype_0|rep_2',
#  'subtype_0|rep_3',
#  'subtype_1|rep_0',
#  'subtype_1|rep_1',
#  'subtype_1|rep_2',
#  'subtype_1|rep_3',
#  'subtype_2|rep_0',
#  'subtype_2|rep_1',
#  'subtype_2|rep_2',
#  'subtype_2|rep_3',
#  'subtype_3|rep_0',
#  'subtype_3|rep_1',
#  'subtype_3|rep_2',
#  'subtype_3|rep_3',
#  'subtype_4|rep_0',
#  'subtype_4|rep_1',
#  'subtype_4|rep_2',
#  'subtype_4|rep_3']

6voto

shoyer Points 4449

Oui, c'est exactement ce que le .stack est pour :

In [33]: stacked = DA_data.stack(desired=['subtype', 'replicates'])

In [34]: stacked
Out[34]:
<xarray.DataArray (attributes: 100, desired: 20)>
array([[ 0.54020268,  0.14914837,  0.83398895, ...,  0.25986503,
         0.62520466,  0.08617668],
       [ 0.47021735,  0.10627027,  0.66666478, ...,  0.84392176,
         0.64461418,  0.4444864 ],
       [ 0.4065543 ,  0.59817851,  0.65033094, ...,  0.01747058,
         0.94414244,  0.31467342],
       ...,
       [ 0.23724934,  0.61742922,  0.97563316, ...,  0.62966631,
         0.89513904,  0.20139552],
       [ 0.21157447,  0.43868899,  0.77488211, ...,  0.98285015,
         0.24367352,  0.8061804 ],
       [ 0.21518079,  0.234854  ,  0.18294781, ...,  0.64679141,
         0.49678393,  0.32215219]])
Coordinates:
  * attributes  (attributes) |S7 'attr_0' 'attr_1' 'attr_2' 'attr_3' ...
  * desired     (desired) object ('subtype_0', 'rep_0') ...

La coordonnée empilée qui en résulte est une pandas.MultiIndex dont les valeurs sont données par des tuples :

In [35]: stacked['desired'].values
Out[35]:
array([('subtype_0', 'rep_0'), ('subtype_0', 'rep_1'),
       ('subtype_0', 'rep_2'), ('subtype_0', 'rep_3'),
       ('subtype_1', 'rep_0'), ('subtype_1', 'rep_1'),
       ('subtype_1', 'rep_2'), ('subtype_1', 'rep_3'),
       ('subtype_2', 'rep_0'), ('subtype_2', 'rep_1'),
       ('subtype_2', 'rep_2'), ('subtype_2', 'rep_3'),
       ('subtype_3', 'rep_0'), ('subtype_3', 'rep_1'),
       ('subtype_3', 'rep_2'), ('subtype_3', 'rep_3'),
       ('subtype_4', 'rep_0'), ('subtype_4', 'rep_1'),
       ('subtype_4', 'rep_2'), ('subtype_4', 'rep_3')], dtype=object)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X