@exporter.export
@preprocess_xarray
def reduce_point_density(points, radius, priority=None):
    'Return a mask to reduce the density of points in irregularly-spaced data.\n\n    This function is used to down-sample a collection of scattered points (e.g. surface\n    data), returning a mask that can be used to select the points from one or more arrays\n    (e.g. arrays of temperature and dew point). The points selected can be controlled by\n    providing an array of ``priority`` values (e.g. rainfall totals to ensure that\n    stations with higher precipitation remain in the mask). The points and radius can be\n    specified with units. If none are provided, meters are assumed.\n\n    Parameters\n    ----------\n    points : (N, K) array-like\n        N locations of the points in K dimensional space\n    radius : `pint.Quantity` or float\n        Minimum radius allowed between points. If units are not provided, meters is assumed.\n    priority : (N, K) array-like, optional\n        If given, this should have the same shape as ``points``; these values will\n        be used to control selection priority for points.\n\n    Returns\n    -------\n        (N,) array-like of boolean values indicating whether points should be kept. This\n        can be used directly to index numpy arrays to return only the desired points.\n\n    Examples\n    --------\n    >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.)\n    array([ True, False, True])\n    >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.,\n    ... priority=np.array([0.1, 0.9, 0.3]))\n    array([False, True, False])\n\n    '
    if hasattr(radius, 'units'):
        radius = radius.to('m').m
    if hasattr(points, 'units'):
        points = points.to('m').m
    if (points.ndim < 2):
        points = points.reshape((- 1), 1)
    tree = cKDTree(points)
    if (priority is not None):
        sorted_indices = np.argsort(priority)[::(- 1)]
    else:
        sorted_indices = range(len(points))
    keep = np.ones(len(points), dtype=np.bool)
    for ind in sorted_indices:
        if keep[ind]:
            neighbors = tree.query_ball_point(points[ind], radius)
            keep[neighbors] = False
            keep[ind] = True
    return keep
Return a mask to reduce the density of points in irregularly-spaced data.

This function is used to down-sample a collection of scattered points (e.g. surface
data), returning a mask that can be used to select the points from one or more arrays
(e.g. arrays of temperature and dew point). The points selected can be controlled by
providing an array of ``priority`` values (e.g. rainfall totals to ensure that
stations with higher precipitation remain in the mask). The points and radius can be
specified with units. If none are provided, meters are assumed.

Parameters
----------
points : (N, K) array-like
    N locations of the points in K dimensional space
radius : `pint.Quantity` or float
    Minimum radius allowed between points. If units are not provided, meters is assumed.
priority : (N, K) array-like, optional
    If given, this should have the same shape as ``points``; these values will
    be used to control selection priority for points.

Returns
-------
    (N,) array-like of boolean values indicating whether points should be kept. This
    can be used directly to index numpy arrays to return only the desired points.

Examples
--------
>>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.)
array([ True, False, True])
>>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.,
... priority=np.array([0.1, 0.9, 0.3]))
array([False, True, False])
@exporter.export
@preprocess_xarray
def reduce_point_density(points, radius, priority=None):
    'Return a mask to reduce the density of points in irregularly-spaced data.\n\n    This function is used to down-sample a collection of scattered points (e.g. surface\n    data), returning a mask that can be used to select the points from one or more arrays\n    (e.g. arrays of temperature and dew point). The points selected can be controlled by\n    providing an array of ``priority`` values (e.g. rainfall totals to ensure that\n    stations with higher precipitation remain in the mask). The points and radius can be\n    specified with units. If none are provided, meters are assumed.\n\n    Parameters\n    ----------\n    points : (N, K) array-like\n        N locations of the points in K dimensional space\n    radius : `pint.Quantity` or float\n        Minimum radius allowed between points. If units are not provided, meters is assumed.\n    priority : (N, K) array-like, optional\n        If given, this should have the same shape as ``points``; these values will\n        be used to control selection priority for points.\n\n    Returns\n    -------\n        (N,) array-like of boolean values indicating whether points should be kept. This\n        can be used directly to index numpy arrays to return only the desired points.\n\n    Examples\n    --------\n    >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.)\n    array([ True, False, True])\n    >>> metpy.calc.reduce_point_density(np.array([1, 2, 3]), 1.,\n    ... priority=np.array([0.1, 0.9, 0.3]))\n    array([False, True, False])\n\n    '
    if hasattr(radius, 'units'):
        radius = radius.to('m').m
    if hasattr(points, 'units'):
        points = points.to('m').m
    if (points.ndim < 2):
        points = points.reshape((- 1), 1)
    tree = cKDTree(points)
    if (priority is not None):
        sorted_indices = np.argsort(priority)[::(- 1)]
    else:
        sorted_indices = range(len(points))
    keep = np.ones(len(points), dtype=np.bool)
    for ind in sorted_indices:
        if keep[ind]:
            neighbors = tree.query_ball_point(points[ind], radius)
            keep[neighbors] = False
            keep[ind] = True
    return keep