es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Extraer valores en ubicaciones puntuales de un DataArray de xarray y obtener todos los demás valores por separado.

Tengo un DataArray xarray de la siguiente manera:

import xarray as xr
import numpy as np

da = xr.DataArray(np.arange(25).reshape(5, 5), dims=['x', 'y'], coords={'x': np.arange(5), 'y': np.arange(5)})

Se ve así:

Imagen del DataArray

Quiero seleccionar los valores del DataArray que están más cerca de ciertos puntos de coordenadas x, y que tengo.

Para hacer esto, puedo poner esas coordenadas de puntos en DataArrays ellos mismos e indexar usando esos:

x_coords = xr.DataArray([1.2, 3.6, 4.9])
y_coords = xr.DataArray([2.2, 0.7, 4.3])

da.sel(x=x_coords, y=y_coords, method='nearest')

Esto da como resultado esperado [7, 21, 24].

Sin embargo, ahora quiero obtener los elementos ‘otros’ del array. Es decir, aquellos que están en celdas que no son las celdas más cercanas a las ubicaciones de los puntos que he dado. En este caso, esto sería todos los números del 0 al 24 excluyendo 7, 21 y 24. Sin embargo, en mi array real, los valores no son únicos como este.

¿Cómo puedo obtener estos valores?

Me pregunté si podría hacer algo usando conjuntos, pero tendría que tratar las coordenadas x e y juntas, ya que las coordenadas vienen en pares, y no pude entender cómo hacer esto.

Si es necesario, estoy contento con una solución solo de numpy, pero preferiría una solución pura de xarray.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una forma de obtener los “otros” elementos del array es crear una nueva DataArray que contenga todas las ubicaciones de las celdas, y luego usar la función setdiff1d de numpy para encontrar qué celdas no son las más cercanas a los puntos dados. Aquí tienes un ejemplo de implementación:

    import numpy as np
    import xarray as xr
    
    da = xr.DataArray(np.arange(25).reshape(5, 5), dims=['x', 'y'], coords={'x': np.arange(5), 'y': np.arange(5)})
    
    # definir los puntos de los que queremos encontrar las celdas más cercanas
    x_coords = xr.DataArray([1.2, 3.6, 4.9])
    y_coords = xr.DataArray([2.2, 0.7, 4.3])
    
    # encontrar las celdas más cercanas para cada punto
    nearest = da.sel(x=x_coords, y=y_coords, method='nearest')
    
    # crear una nueva DataArray con todas las ubicaciones de las celdas
    all_cells = xr.DataArray(np.ones(da.shape), dims=['x', 'y'], coords=da.coords)
    
    # encontrar qué celdas no son las más cercanas a ninguno de los puntos dados
    not_nearest = all_cells.where(~np.isin(all_cells, nearest)).stack(cell=['x', 'y']).dropna('cell')
    
    # obtener los valores de las "otras" celdas
    other_values = da.values.flatten()[not_nearest.index]
    

    La DataArray not_nearest tiene el valor 1 para todas las celdas que no son las más cercanas a ninguno de los puntos dados, y NaN para el resto. Al empilar las coordenadas x e y en una nueva dimensión cell, podemos utilizar la función dropna para mantener solo las celdas donde el valor sea 1.

    Finalmente, podemos utilizar la función flatten de numpy para convertir la DataArray original en un array unidimensional, y utilizar el índice not_nearest.index para obtener los valores de las “otras” celdas. Ten en cuenta que los valores se devuelven en el orden del array aplanado, no en el orden del array original.

Comments are closed.