import numpy as np
from impactlab_tools.utils.weighting import weighted_quantile_xr, _get_weights
[docs]
def gcp_quantiles(
data,
rcp=None,
quantiles=[0.05, 0.17, 0.5, 0.83, 0.95],
values_sorted=False,
dim='model',
sample_weight=None):
"""
Compute quantiles of an xarray distribution using GCP weights
.. NOTE ::
This function does not control for the number of samples of each model.
If they are not constant across models provide a correctly weighted
weights array to :py:func:`utils.weighting.weighted_quantile_xr`.
We would like to fix this. If you have a good fix we'd love a PR :)
Parameters
----------
data : DataArray or Dataset
:py:class:`xarray.DataArray` or :py:class:`xarray.Dataset` with data
indexed by GCP model along the dimension ``dim``. If a Dataset is
passed, ``gcp_quantiles`` computes the weighted quantile for each
variable in the ``Dataset`` that is indexed by ``dim``.
rcp : str, optional
RCP weights/models to use ('rcp45', 'rcp85'). Required if no
``sample_weight`` provided.
quantiles : array-like
quantiles of distribution to return. quantiles should be in [0, 1].
values_sorted : bool
if True, then will avoid sorting of initial array
dim : str, optional
dimension along which to retrieve quantiles. The indices of this
dimension should be valid (case insensitive) GCP climate models.
Default: `'model'`.
sample_weight : DataArray, optional
weights to use when producing the weighted quantiles. Required
if no RCP provided. If not provided, uses the defualt weights
for the RCP provided, based on Rasmussen et al. (2015).
Returns
-------
DataArray or Dataset
returns a new :py:class:`~xarray.DataArray` or
:py:class:`~xarray.Dataset` with quantiles computed from weighted
distribution along a new dimension ``quantile`` and dimension ``dim``
dropped.
See also
--------
* :py:func:`.acp.dist.acp_quantiles`
* :py:func:`.utils.weighting.weighted_quantile_xr`
* :py:func:`.utils.weighting.weighted_quantile`
* :py:func:`.utils.weighting.weighted_quantile_1d`
* :py:func:`numpy.percentile`
* :py:meth:`xarray.Dataset.quantile`
* :py:meth:`xarray.DataArray.quantile`
* :py:meth:`pandas.DataFrame.quantile`
* :py:meth:`pandas.Series.quantile`
"""
# prep weight
if sample_weight is None:
sample_weight = _get_weights(project='gcp', rcp=rcp)
sample_weight = sample_weight.rename({'model': dim})
# prepare arrays of models to align along `dim` (case insensitive)
models_in_data = data.coords[dim].values
models_in_data_aligned = np.array([m.lower() for m in models_in_data])
# align weights to match ordering of models (using lowercase models)
sample_weight = sample_weight.sel(**{dim: models_in_data_aligned})
# swap weights coordinate to use model names from data
sample_weight.coords[dim] = models_in_data
return weighted_quantile_xr(
data, quantiles, sample_weight=sample_weight, dim=dim)