web-dev-qa-db-fra.com

interpolation inverse xarray (sur les coordonnées, pas sur les données)

J'ai un DataArray suivant

arr = xr.DataArray([[0.33, 0.25],[0.55, 0.60],[0.85, 0.71],[0.92,0.85],[1.50,0.96],[2.5,1.1]],[('x',[0.25,0.5,0.75,1.0,1.25,1.5]),('y',[1,2])])

Cela donne la sortie suivante

<xarray.DataArray (x: 6, y: 2)>
array([[0.33, 0.25],
       [0.55, 0.6 ],
       [0.85, 0.71],
       [0.92, 0.85],
       [1.5 , 0.96],
       [2.5 , 1.1 ]])
Coordinates:
  * x        (x) float64 0.25 0.5 0.75 1.0 1.25 1.5
  * y        (y) int32 1 2

ou triés ci-dessous avec x et sortie (z) côte à côte pour plus de commodité.

x         z (y=1)   z(y=2)
0.25      0.33      0.25
0.50      0.55      0.60
0.75      0.85      0.71
1.00      0.92      0.85
1.25      1.50      0.96
1.50      2.50      1.10

Les données que j'ai sont le résultat de plusieurs valeurs d'entrée. L'un d'eux est la valeur x. Il existe plusieurs autres dimensions (telles que y) pour les autres valeurs d'entrée. Je veux savoir quand ma valeur de sortie (z) dépasse 1,00, en gardant les autres dimensions fixes et en faisant varier la valeur x. Dans l'exemple à 2 dimensions ci-dessus, je voudrais obtenir la réponse [1.03 1.32]. Parce qu'une valeur de 1,03 pour x me donnera 1,00 pour z lorsque y = 1 et une valeur de 1,32 pour x me donnera 1,00 pour z lorsque y = 2.

edit: Puisque la sortie z augmentera avec l'augmentation de x, il n'y a qu'un seul point où z aura 1.0 comme sortie.

Existe-t-il un moyen efficace d'y parvenir avec xarray? Ma table actuelle est beaucoup plus grande et comporte 4 entrées (dimensions).

Merci pour toute aide!

9
Hoogendijk

Le problème que j'ai eu avec la réponse de jojo est qu'il est difficile de l'étendre dans de nombreuses dimensions et de conserver la structure de la radiographie. Par conséquent, j'ai décidé d'approfondir cette question. J'ai utilisé quelques idées du code de jojo pour faire la réponse ci-dessous.

Je crée deux tableaux, l'un avec la condition que les valeurs soient plus petites que ce que je recherche, et l'autre avec la condition dont elles doivent être plus grandes. Je décale le second dans la direction x de moins 1. Maintenant, je les combine dans une formule d'interpolation linéaire normale. Les deux tableaux ont uniquement des valeurs qui se chevauchent au "bord" de la condition. Si elle n'est pas décalée de -1, aucune valeur ne se chevaucherait. Dans la dernière ligne, je somme sur la direction x et comme toutes les autres valeurs sont NaN, j'extrais la valeur correcte et supprime la direction x du DataArray dans le processus.

def interpolate_dimension_x(arr, target_value, step):
    M0 = arr.where(arr - target_value <= 0)
    M1 = arr.where(arr - target_value > 0).shift(x=-1)

    work_mat = M0.x + step * (target_value - M0) / (M1 - M0)

    return work_mat.sum(dim='x')
interpolate_dimension_x(arr, 1, 0.25)

>>> <xarray.DataArray (y: 2)>
array([1.034483, 1.321429])
Coordinates:
  * y        (y) int32 1 2

J'ai quelques inconvénients avec mon code. Le code ne fonctionne que si M0 et M1 trouvent une valeur qui remplit la condition. Sinon, toutes les valeurs de cette ligne seront définies sur NaN. Pour éviter les problèmes avec M0, j'ai décidé que les valeurs x commencent simplement à 0 car ma valeur cible est toujours supérieure à 0. Pour éviter les problèmes avec M1, je choisis mes valeurs de x assez grandes pour que je sache que mes valeurs sont là . Naturellement, ce ne sont pas des solutions idéales et peuvent casser le code. Si j'obtiens un peu plus d'expérience avec xarray et python je pourrais réécrire. En résumé, j'ai les éléments suivants que je voudrais résoudre:

  • Comment extrapoler des valeurs en dehors de la plage X? Je suis actuellement juste en train de m'assurer que ma plage X est suffisamment grande pour que les réponses y correspondent.
  • Comment rendre le code robuste pour une taille de pas variable?
  • Comment faire le code pour que ma dimension puisse être choisie dynamiquement (maintenant cela ne fonctionne que pour 'x')
  • Toutes les optimisations sont appréciées.
1
Hoogendijk