xrspatial.focal.apply#

xrspatial.focal.apply(raster, kernel, func=CPUDispatcher(<function _calc_mean>), name='focal_apply')[source]#

Returns custom function applied array using a user-created window.

Parameters
  • raster (xarray.DataArray) – 2D array of input values to be filtered. Can be a NumPy backed, or Dask with NumPy backed DataArray.

  • kernel (numpy.ndarray) – 2D array where values of 1 indicate the kernel.

  • func (callable, default=xrspatial.focal._calc_mean) – Function which takes an input array and returns an array.

Returns

agg – 2D aggregate array of filtered values.

Return type

xarray.DataArray of same type as raster

Examples

Focal apply works with NumPy backed xarray DataArray .. sourcecode:: python

>>> import numpy as np
>>> import xarray as xr
>>> from xrspatial.convolution import circle_kernel
>>> from xrspatial.focal import apply
>>> data = np.arange(20, dtype=np.float64).reshape(4, 5)
>>> raster = xr.DataArray(data, dims=['y', 'x'], name='raster')
>>> print(raster)
<xarray.DataArray 'raster' (y: 4, x: 5)>
array([[ 0.,  1.,  2.,  3.,  4.],
       [ 5.,  6.,  7.,  8.,  9.],
       [10., 11., 12., 13., 14.],
       [15., 16., 17., 18., 19.]])
Dimensions without coordinates: y, x
>>> kernel = circle_kernel(2, 2, 3)
>>> kernel
array([[0., 1., 0.],
       [1., 1., 1.],
       [0., 1., 0.]])
>>> # apply kernel mean by default
>>> apply_mean_agg = apply(raster, kernel)
>>> apply_mean_agg
<xarray.DataArray 'focal_apply' (y: 4, x: 5)>
array([[ 2.        ,  2.25   ,  3.25      ,  4.25      ,  5.33333333],
       [ 5.25      ,  6.     ,  7.        ,  8.        ,  8.75      ],
       [10.25      , 11.     , 12.        , 13.        , 13.75      ],
       [13.66666667, 14.75   , 15.75      , 16.75      , 17.        ]])
Dimensions without coordinates: y, x

Focal apply works with Dask with NumPy backed xarray DataArray. Note that if input raster is a numpy or dask with numpy backed data array, the applied function must be decorated with numba.jit xrspatial already provides ngjit decorator, where: ngjit = numba.jit(nopython=True, nogil=True)


>>> from xrspatial.utils import ngjit
>>> from xrspatial.convolution import custom_kernel
>>> kernel = custom_kernel(np.array([
    [0, 1, 0],
    [0, 1, 1],
    [0, 1, 0],
]))
>>> weight = np.array([
    [0, 0.5, 0],
    [0, 1, 0.5],
    [0, 0.5, 0],
])
>>> @ngjit
>>> def func(kernel_data):
...     weight = np.array([
...         [0, 0.5, 0],
...         [0, 1, 0.5],
...         [0, 0.5, 0],
...     ])
...     return np.nansum(kernel_data * weight)
>>> import dask.array as da
>>> data_da = da.from_array(np.ones((6, 4), dtype=np.float64), chunks=(3, 2))
>>> raster_da = xr.DataArray(data_da, dims=['y', 'x'], name='raster_da')
>>> print(raster_da)
<xarray.DataArray 'raster_da' (y: 6, x: 4)>
dask.array<array, shape=(6, 4), dtype=float64, chunksize=(3, 2), chunktype=numpy.ndarray>  # noqa
Dimensions without coordinates: y, x
>>> apply_func_agg = apply(raster_da, kernel, func)
>>> print(apply_func_agg)
<xarray.DataArray 'focal_apply' (y: 6, x: 4)>
dask.array<_trim, shape=(6, 4), dtype=float64, chunksize=(3, 2), chunktype=numpy.ndarray>  # noqa
Dimensions without coordinates: y, x
>>> print(apply_func_agg.compute())
<xarray.DataArray 'focal_apply' (y: 6, x: 4)>
array([[2. , 2. , 2. , 1.5],
       [2.5, 2.5, 2.5, 2. ],
       [2.5, 2.5, 2.5, 2. ],
       [2.5, 2.5, 2.5, 2. ],
       [2.5, 2.5, 2.5, 2. ],
       [2. , 2. , 2. , 1.5]])
Dimensions without coordinates: y, x