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.

Coarsen xarray DataArray with weighted mean would be translated to: Coarsen el DataArray de xarray con la media ponderada.

Digamos que tengo un DataArray:

da = xr.DataArray(
    data=np.random.random((25,25)),
    dims=["x", "y"],
    coords=dict(
        x=np.arange(25),
        y=np.arange(25),
    ),
)

Quiero reducir la resolución de esta matriz a grupos de 5×5. Puedo hacer esto con la función ‘coarsen’:

da_coarse = da.coarsen(x=5,y=5).mean()

Según entiendo, esto básicamente divide el DataArray en “grupos” de 5×5 y calcula el promedio de cada grupo en un único valor. Sin embargo, lo que quiero hacer es tomar un promedio ponderado de este grupo de 5×5, de manera que los puntos centrales tengan más peso en la media final que los puntos de los bordes.

Puedo crear un kernel gaussiano con pesos de la siguiente manera:

def gkern(kernlen=21, sig=3):
    import scipy.stats as st

    """Devuelve un kernel gaussiano 2D."""
    x = np.linspace(-(kernlen/2)/sig, (kernlen/2)/sig, kernlen+1)
    kern1d = np.diff(st.norm.cdf(x))
    kern2d = np.outer(kern1d, kern1d)
    return kern2d/kern2d.sum()

window = gkern(5)

Donde ‘window’ es ahora una matriz de 5×5 con los pesos deseados para cada punto. Sin embargo, no estoy seguro de cómo implementar esta ventana/kernel al realizar la media en la función ‘coarsen’.

¿Cuál es la mejor manera de hacer esto?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para utilizar el kernel window en la función coarsen, puedes pasarlo como parámetro al argumento func. Puedes utilizar la función scipy.ndimage.convolve para calcular el promedio ponderado de cada fragmento utilizando el kernel window.

    Así es como puedes modificar tu código para obtener el resultado deseado:

    import numpy as np
    import scipy.ndimage as nd
    import scipy.stats as st
    import xarray as xr
    
    def gkern(kernlen=21, sig=3):
        """Devuelve un kernel Gaussiano 2D."""
        x = np.linspace(-(kernlen/2)/sig, (kernlen/2)/sig, kernlen+1)
        kern1d = np.diff(st.norm.cdf(x))
        kern2d = np.outer(kern1d, kern1d)
        return kern2d/kern2d.sum()
    
    # Generar un arreglo de datos aleatorios
    da = xr.DataArray(
        data=np.random.random((25,25)),
        dims=["x", "y"],
        coords=dict(
            x=np.arange(25),
            y=np.arange(25),
        ),
    )
    
    # Crear el kernel window
    window = gkern(5)
    
    # Definir la función de promedio ponderado utilizando el kernel window
    def weighted_average(chunk):
        return np.sum(chunk * window) / np.sum(window)
    
    # Utilizar coarsen con la función weighted_average y el kernel window
    da_coarse = da.coarsen(x=5, y=5, func=weighted_average)
    

    En este código, definimos la función weighted_average que toma un fragmento de datos y lo multiplica por el kernel window antes de sumar y dividir por la suma de los pesos en la ventana. Luego pasamos esta función como parámetro func al método coarsen junto con el kernel window. El resultado es un DataArray remuestreado con promedio ponderado de los fragmentos de 5×5.

Comments are closed.