median_abs_deviation

xarray_einstats.stats.median_abs_deviation(da, dims=None, *, center=None, scale=1, nan_policy=None, **kwargs)[source]

Wrap and extend scipy.stats.median_abs_deviation.

Usage examples available at Intro to the stats module.

All parameters take the same values and types as the scipy counterpart with the exception of scale. Here scale can also take DataArray values in which case, broadcasting is handled by xarray, as shown in the example.

Examples

Use a DataArray as scale.

import xarray as xr
from xarray_einstats import tutorial, stats
ds = tutorial.generate_mcmc_like_dataset(3)
s_da = xr.DataArray([1, 2, 1, 1], coords={"chain": ds.chain})
stats.median_abs_deviation(ds["mu"], dims="draw", scale=s_da)
<xarray.DataArray 'mu' (chain: 4, team: 6)> Size: 192B
0.3468 0.4532 0.5054 0.876 0.6265 0.7342 ... 0.4382 0.5668 0.7103 0.2494 0.3485
Coordinates:
  * chain    (chain) int64 32B 0 1 2 3
  * team     (team) <U1 24B 'a' 'b' 'c' 'd' 'e' 'f'

Note that this doesn’t work with the scipy counterpart because s_da can’t be broadcasted with the output:

from scipy import stats
stats.median_abs_deviation(ds["mu"], axis=1, scale=s_da)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 2
      1 from scipy import stats
----> 2 stats.median_abs_deviation(ds["mu"], axis=1, scale=s_da)

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/scipy/stats/_axis_nan_policy.py:635, in _axis_nan_policy_factory.<locals>.axis_nan_policy_decorator.<locals>.axis_nan_policy_wrapper(***failed resolving arguments***)
    632     contains_nan = False  # behave like there are no NaNs
    634 if vectorized and not contains_nan and not sentinel:
--> 635     res = hypotest_fun_out(*samples, axis=axis, **kwds)
    636     res = result_to_tuple(res, n_out)
    637     res = _add_reduced_axes(res, reduced_axes, keepdims)

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/scipy/stats/_stats_py.py:3371, in median_abs_deviation(x, axis, center, scale, nan_policy)
   3368 med = xp.expand_dims(center(x, axis=axis), axis=axis)
   3369 mad = xp_median(xp.abs(x - med), axis=axis)
-> 3371 return mad / scale

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/xarray/computation/arithmetic.py:84, in SupportsArithmetic.__array_ufunc__(self, ufunc, method, *inputs, **kwargs)
     75     raise NotImplementedError(
     76         "xarray objects are not yet supported in the `out` argument "
     77         "for ufuncs. As an alternative, consider explicitly "
     78         "converting xarray objects to NumPy arrays (e.g., with "
     79         "`.values`)."
     80     )
     82 join = dataset_join = OPTIONS["arithmetic_join"]
---> 84 return apply_ufunc(
     85     ufunc,
     86     *inputs,
     87     input_core_dims=((),) * ufunc.nin,
     88     output_core_dims=((),) * ufunc.nout,
     89     join=join,
     90     dataset_join=dataset_join,
     91     dataset_fill_value=np.nan,
     92     kwargs=kwargs,
     93     dask="allowed",
     94     keep_attrs=_get_keep_attrs(default=True),
     95 )

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/xarray/computation/apply_ufunc.py:1267, in apply_ufunc(func, input_core_dims, output_core_dims, exclude_dims, vectorize, join, dataset_join, dataset_fill_value, keep_attrs, kwargs, dask, output_dtypes, output_sizes, meta, dask_gufunc_kwargs, on_missing_core_dim, *args)
   1265 # feed DataArray apply_variable_ufunc through apply_dataarray_vfunc
   1266 elif any(isinstance(a, DataArray) for a in args):
-> 1267     return apply_dataarray_vfunc(
   1268         variables_vfunc,
   1269         *args,
   1270         signature=signature,
   1271         join=join,
   1272         exclude_dims=exclude_dims,
   1273         keep_attrs=keep_attrs,
   1274     )
   1275 # feed Variables directly through apply_variable_ufunc
   1276 elif any(isinstance(a, Variable) for a in args):

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/xarray/computation/apply_ufunc.py:312, in apply_dataarray_vfunc(func, signature, join, exclude_dims, keep_attrs, *args)
    307 result_coords, result_indexes = build_output_coords_and_indexes(
    308     args, signature, exclude_dims, combine_attrs=keep_attrs
    309 )
    311 data_vars = [getattr(a, "variable", a) for a in args]
--> 312 result_var = func(*data_vars)
    314 out: tuple[DataArray, ...] | DataArray
    315 if signature.num_outputs > 1:

File ~/checkouts/readthedocs.org/user_builds/xarray-einstats/envs/88/lib/python3.12/site-packages/xarray/computation/apply_ufunc.py:820, in apply_variable_ufunc(func, signature, exclude_dims, dask, output_dtypes, vectorize, keep_attrs, dask_gufunc_kwargs, *args)
    815 elif vectorize:
    816     func = _vectorize(
    817         func, signature, output_dtypes=output_dtypes, exclude_dims=exclude_dims
    818     )
--> 820 result_data = func(*input_data)
    822 if signature.num_outputs == 1:
    823     result_data = (result_data,)

ValueError: operands could not be broadcast together with shapes (4,6) (4,)