Repository: xarray-contrib/xskillscore

Issue:
raise error if forecast doesn't contain coords in resample_iterations_idx
`a = xr.DataArray(np.random.rand(1000, 3, 3), dims=['time', 'x', 'y'])`
doesn't work in 
`xs.resample_iterations_idx(a, 500, 'time')`

```
xr.DataArray(
    np.random.rand(1000, 3, 3),
    coords=[("time", np.arange(1000)), ("x", np.arange(3)), ("y", np.arange(3))],
)
```
does.

Taken from https://github.com/xarray-contrib/xskillscore/pull/302#issuecomment-832863346

Comments:

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 4a955fd..40f2270 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 e4f1096..5481029 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 resample_iterations_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


Test patch:
diff --git a/xskillscore/tests/test_resampling.py b/xskillscore/tests/test_resampling.py
index 6d09fe3..572a55c 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