diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4a955fd9..40f22701 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,11 @@ Changelog History xskillscore v0.0.23 (2021-xx-xx) -------------------------------- +Internal Changes +~~~~~~~~~~~~~~~~ +- :py:func:`~xskillscore.resampling.resample_iterations_idx` do not break when ``dim`` is + not coordinate. (:issue:`303`, :pr:`339`) `Aaron Spring`_ + xskillscore v0.0.22 (2021-06-29) -------------------------------- diff --git a/xskillscore/core/resampling.py b/xskillscore/core/resampling.py index e4f1096d..5481029c 100644 --- a/xskillscore/core/resampling.py +++ b/xskillscore/core/resampling.py @@ -107,6 +107,8 @@ def resample_iterations(forecast, iterations, dim="member", dim_max=None, replac forecast_smp.append(forecast.isel({dim: idx}).assign_coords({dim: new_dim})) forecast_smp = xr.concat(forecast_smp, dim="iteration", **CONCAT_KWARGS) forecast_smp["iteration"] = np.arange(iterations) + if dim not in forecast.coords: + del forecast_smp.coords[dim] return forecast_smp.transpose(..., "iteration") @@ -172,7 +174,12 @@ def resample_iterations_idx( for interannual-to-decadal predictions experiments. Climate Dynamics, 40(1–2), 245–272. https://doi.org/10/f4jjvf """ - # equivalent to above + if dim not in forecast.coords: + forecast.coords[dim] = np.arange(0, forecast[dim].size) + dim_coord_set = True + else: + dim_coord_set = False + select_dim_items = forecast[dim].size new_dim = forecast[dim] @@ -205,4 +212,6 @@ def select_bootstrap_indices_ufunc(x, idx): # return only dim_max members if dim_max is not None and dim_max <= forecast[dim].size: forecast_smp = forecast_smp.isel({dim: slice(None, dim_max)}) + if dim_coord_set: + del forecast_smp.coords[dim] return forecast_smp diff --git a/xskillscore/tests/test_resampling.py b/xskillscore/tests/test_resampling.py index 6d09fe30..572a55c9 100644 --- a/xskillscore/tests/test_resampling.py +++ b/xskillscore/tests/test_resampling.py @@ -154,3 +154,14 @@ def test_resample_inputs(a_1d, func, input, chunk, replace): assert is_dask_collection(actual) if chunk else not is_dask_collection(actual) # input type preserved assert type(actual) == type(a_1d) + + +@pytest.mark.parametrize("func", resample_iterations_funcs) +def test_resample_dim_no_coord(func): + """resample_iterations doesnt fail when no dim coords""" + da = xr.DataArray( + np.random.rand(100, 3, 3), + coords=[("time", np.arange(100)), ("x", np.arange(3)), ("y", np.arange(3))], + ) + del da.coords["time"] + assert "time" not in func(da, 2, dim="time").coords