Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ you should jump to {ref}`array_stats_api` and read forward.
arviz_stats.ci_in_rope
arviz_stats.ecdf
arviz_stats.eti
arviz_stats.iqr
arviz_stats.hdi
arviz_stats.histogram
arviz_stats.kde
Expand All @@ -57,13 +58,16 @@ you should jump to {ref}`array_stats_api` and read forward.
arviz_stats.loo_metrics
arviz_stats.loo_r2
arviz_stats.loo_score
arviz_stats.mad
arviz_stats.mean
arviz_stats.median
arviz_stats.metrics
arviz_stats.mode
arviz_stats.qds
arviz_stats.residual_r2
arviz_stats.std
arviz_stats.summary
arviz_stats.var
arviz_stats.wasserstein
```

Expand Down
2 changes: 1 addition & 1 deletion src/arviz_stats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from arviz_stats.psense import psense, psense_summary
from arviz_stats.metrics import bayesian_r2, kl_divergence, metrics, residual_r2, wasserstein
from arviz_stats.sampling_diagnostics import bfmi, ess, mcse, rhat, rhat_nested, diagnose
from arviz_stats.summary import summary, ci_in_rope, mean, median, mode
from arviz_stats.summary import summary, ci_in_rope, mean, median, mode, std, var, iqr, mad
from arviz_stats.manipulation import thin, weight_predictions
from arviz_stats.bayes_factor import bayes_factor
from arviz_stats.visualization import ecdf, eti, hdi, histogram, kde, qds
Expand Down
16 changes: 16 additions & 0 deletions src/arviz_stats/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,22 @@ def mode(self, dim=None, **kwargs):
"""Compute mode for all variables in the dataset."""
return self._apply("mode", dim=dim, **kwargs)

def std(self, dim=None, **kwargs):
"""Compute standard deviation for all variables in the dataset."""
return self._apply("std", dim=dim, **kwargs)

def var(self, dim=None, **kwargs):
"""Compute variance for all variables in the dataset."""
return self._apply("var", dim=dim, **kwargs)

def mad(self, dim=None, **kwargs):
"""Compute median absolute deviation for all variables in the dataset."""
return self._apply("mad", dim=dim, **kwargs)

def iqr(self, dim=None, **kwargs):
"""Compute interquantile range for all variables in the dataset."""
return self._apply("iqr", dim=dim, **kwargs)

def srs_estimator(self, n_data_points, **kwargs):
"""Compute simple random sampling estimate for subsampled LOO."""
return self._apply(
Expand Down
130 changes: 128 additions & 2 deletions src/arviz_stats/base/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ def mean(self, ary, round_to=None, skipna=False, axis=None):
skipna : bool, default False
Whether to ignore NaN values when computing the mean.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the mode.
Axis or axes along which to compute the mean.

Returns
-------
Expand Down Expand Up @@ -804,7 +804,7 @@ def median(self, ary, round_to=None, skipna=False, axis=None):
skipna : bool, default False
Whether to ignore NaN values when computing the median.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the mode.
Axis or axes along which to compute the median.

Returns
-------
Expand Down Expand Up @@ -852,6 +852,132 @@ def mode(self, ary, round_to=None, skipna=False, axis=None):
)
return mode_ufunc(ary, round_to=round_to, skipna=skipna)

def std(self, ary, round_to=None, skipna=False, axis=None):
"""Compute standard deviation of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
Whether to ignore NaN values when computing the standard deviation.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the standard deviation.

Returns
-------
std : array-like
Standard deviation of the input values along the specified axis.
"""
ary, axes = process_ary_axes(ary, axis)
std_ufunc = make_ufunc(
self._std,
n_output=1,
n_input=1,
n_dims=len(axes),
ravel=False,
)
return std_ufunc(ary, round_to=round_to, skipna=skipna)

def var(self, ary, round_to=None, skipna=False, axis=None):
"""Compute variance of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
Whether to ignore NaN values when computing the variance.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the variance.

Returns
-------
var : array-like
Variance of the input values along the specified axis.
"""
ary, axes = process_ary_axes(ary, axis)
var_ufunc = make_ufunc(
self._var,
n_output=1,
n_input=1,
n_dims=len(axes),
ravel=False,
)
return var_ufunc(ary, round_to=round_to, skipna=skipna)

def mad(self, ary, round_to=None, skipna=False, axis=None):
"""Compute mean absolute deviation of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
Whether to ignore NaN values when computing the mean absolute deviation.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the mean absolute deviation.

Returns
-------
mad : array-like
Mean absolute deviation of the input values along the specified axis.
"""
ary, axes = process_ary_axes(ary, axis)
mad_ufunc = make_ufunc(
self._mad,
n_output=1,
n_input=1,
n_dims=len(axes),
ravel=False,
)
return mad_ufunc(ary, round_to=round_to, skipna=skipna)

def iqr(self, ary, quantiles=(0.25, 0.75), round_to=None, skipna=False, axis=None):
"""Compute interquantile range of values along the specified axis.

Parameters
----------
values : array-like
Input array.
quantiles : tuple of float, default (0.25, 0.75)
Quantiles to compute the interquartile range.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
Whether to ignore NaN values when computing the interquantile range.
axis : int, sequence of int or None, default -1
Axis or axes along which to compute the interquantile range.

Returns
-------
iqr : array-like
Interquantile range of the input values along the specified axis.
"""
ary, axes = process_ary_axes(ary, axis)
iqr_ufunc = make_ufunc(
self._iqr,
n_output=1,
n_input=1,
n_dims=len(axes),
ravel=False,
)
return iqr_ufunc(ary, quantiles=quantiles, round_to=round_to, skipna=skipna)

def loo(
self,
ary,
Expand Down
89 changes: 89 additions & 0 deletions src/arviz_stats/base/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,3 +490,92 @@ def _mode(self, ary, round_to=None, skipna=False):
# For discrete data, we use the most frequent value.
vals, cnts = np.unique(ary, return_counts=True)
return vals[cnts.argmax()]

def _std(self, ary, round_to=None, skipna=False, axis=None):
"""Compute standard deviation of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
If True, ignore NaN values.
axis : int, sequence of int or None, default None
Axis or axes along which to compute the standard deviation.
"""
if skipna:
ary = ary[~np.isnan(ary)]
return round_num(np.std(ary, axis=axis, ddof=1), round_to)

def _var(self, ary, round_to=None, skipna=False, axis=None):
"""Compute variance of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
If True, ignore NaN values.
axis : int, sequence of int or None, default None
Axis or axes along which to compute the variance.
"""
if skipna:
ary = ary[~np.isnan(ary)]
return round_num(np.var(ary, axis=axis, ddof=1), round_to)

def _mad(self, ary, round_to=None, skipna=False, axis=None):
"""Compute median absolute deviation of values along the specified axis.

Parameters
----------
values : array-like
Input array.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
If True, ignore NaN values.
axis : int, sequence of int or None, default None
Axis or axes along which to compute the median absolute deviation.
"""
if skipna:
ary = ary[~np.isnan(ary)]
median = np.median(ary, axis=axis)
mad = np.median(np.abs(ary - median), axis=axis)
return round_num(mad, round_to)

def _iqr(self, ary, quantiles=(0.25, 0.75), round_to=None, skipna=False, axis=None):
"""Compute interquantile range of values along the specified axis.

Parameters
----------
values : array-like
Input array.
quantiles : tuple of two floats, default (0.25, 0.75)
Quantiles to compute the interquantile range. Defaults to (0.25, 0.75), that is,
the interquartile range.
round_to : int or str, optional
If integer, number of decimal places to round the result. If string of the
form '2g' number of significant digits to round the result. Defaults to '2g'.
Use None to return raw numbers.
skipna : bool, default False
If True, ignore NaN values.
axis : int, sequence of int or None, default None
Axis or axes along which to compute the interquartile range.
"""
if skipna:
ary = ary[~np.isnan(ary)]
if ary.size == 0:
return np.nan
q1, q3 = np.quantile(ary, quantiles, axis=axis)
iqr = q3 - q1
return round_num(iqr, round_to)
53 changes: 53 additions & 0 deletions src/arviz_stats/base/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,59 @@ def mode(self, da, round_to=None, skipna=False, dim=None):
kwargs={"round_to": round_to, "skipna": skipna, "axis": np.arange(-len(dims), 0, 1)},
)

def std(self, da, round_to=None, skipna=False, dim=None):
"""Compute standard deviation on DataArray input."""
dims = validate_dims(dim)

return apply_ufunc(
self.array_class.std,
da,
input_core_dims=[dims],
output_core_dims=[[]],
kwargs={"round_to": round_to, "skipna": skipna, "axis": np.arange(-len(dims), 0, 1)},
)

def var(self, da, round_to=None, skipna=False, dim=None):
"""Compute variance on DataArray input."""
dims = validate_dims(dim)

return apply_ufunc(
self.array_class.var,
da,
input_core_dims=[dims],
output_core_dims=[[]],
kwargs={"round_to": round_to, "skipna": skipna, "axis": np.arange(-len(dims), 0, 1)},
)

def mad(self, da, round_to=None, skipna=False, dim=None):
"""Compute median absolute deviation on DataArray input."""
dims = validate_dims(dim)

return apply_ufunc(
self.array_class.mad,
da,
input_core_dims=[dims],
output_core_dims=[[]],
kwargs={"round_to": round_to, "skipna": skipna, "axis": np.arange(-len(dims), 0, 1)},
)

def iqr(self, da, quantiles=(0.25, 0.75), round_to=None, skipna=False, dim=None):
"""Compute interquartile range on DataArray input."""
dims = validate_dims(dim)

return apply_ufunc(
self.array_class.iqr,
da,
input_core_dims=[dims],
output_core_dims=[[]],
kwargs={
"quantiles": quantiles,
"round_to": round_to,
"skipna": skipna,
"axis": np.arange(-len(dims), 0, 1),
},
)

def srs_estimator(self, da, n_data_points):
"""Compute simple random sampling estimate for subsampled LOO on DataArray.

Expand Down
Loading