Skip to content

Commit 755581c

Browse files
dcherianIllviljan
andauthored
Fix interpolation when non-numeric coords are present. (#9887)
* Fix interpolation when non-numeric coords are present. Closes #8099 Closes #9839 * fix * Add basic 1d test --------- Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com>
1 parent f05c5ec commit 755581c

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ Bug fixes
4747
By `Bruce Merry <https://github.com/bmerry>`_.
4848
- Fix unintended load on datasets when calling :py:meth:`DataArray.plot.scatter` (:pull:`9818`).
4949
By `Jimmy Westling <https://github.com/illviljan>`_.
50+
- Fix interpolation when non-numeric coordinate variables are present (:issue:`8099`, :issue:`9839`).
51+
By `Deepak Cherian <https://github.com/dcherian>`_.
52+
5053

5154
Documentation
5255
~~~~~~~~~~~~~

xarray/core/dataset.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4185,7 +4185,7 @@ def _validate_interp_indexer(x, new_x):
41854185
}
41864186

41874187
variables: dict[Hashable, Variable] = {}
4188-
reindex: bool = False
4188+
reindex_vars: list[Hashable] = []
41894189
for name, var in obj._variables.items():
41904190
if name in indexers:
41914191
continue
@@ -4207,19 +4207,20 @@ def _validate_interp_indexer(x, new_x):
42074207
# booleans and objects and retains the dtype but inside
42084208
# this loop there might be some duplicate code that slows it
42094209
# down, therefore collect these signals and run it later:
4210-
reindex = True
4210+
reindex_vars.append(name)
42114211
elif all(d not in indexers for d in var.dims):
42124212
# For anything else we can only keep variables if they
42134213
# are not dependent on any coords that are being
42144214
# interpolated along:
42154215
variables[name] = var
42164216

4217-
if reindex:
4218-
reindex_indexers = {
4217+
if reindex_vars and (
4218+
reindex_indexers := {
42194219
k: v for k, (_, v) in validated_indexers.items() if v.dims == (k,)
42204220
}
4221+
):
42214222
reindexed = alignment.reindex(
4222-
obj,
4223+
obj[reindex_vars],
42234224
indexers=reindex_indexers,
42244225
method=method_non_numeric,
42254226
exclude_vars=variables.keys(),

xarray/tests/test_interp.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,3 +1055,41 @@ def test_interp1d_complex_out_of_bounds() -> None:
10551055
expected = da.interp(time=3.5, kwargs=dict(fill_value=np.nan + np.nan * 1j))
10561056
actual = da.interp(time=3.5)
10571057
assert_identical(actual, expected)
1058+
1059+
1060+
@requires_scipy
1061+
def test_interp_non_numeric_1d() -> None:
1062+
ds = xr.Dataset(
1063+
{
1064+
"numeric": ("time", 1 + np.arange(0, 4, 1)),
1065+
"non_numeric": ("time", np.array(["a", "b", "c", "d"])),
1066+
},
1067+
coords={"time": (np.arange(0, 4, 1))},
1068+
)
1069+
actual = ds.interp(time=np.linspace(0, 3, 7))
1070+
1071+
expected = xr.Dataset(
1072+
{
1073+
"numeric": ("time", 1 + np.linspace(0, 3, 7)),
1074+
"non_numeric": ("time", np.array(["a", "b", "b", "c", "c", "d", "d"])),
1075+
},
1076+
coords={"time": np.linspace(0, 3, 7)},
1077+
)
1078+
xr.testing.assert_identical(actual, expected)
1079+
1080+
1081+
@requires_scipy
1082+
def test_interp_non_numeric_nd() -> None:
1083+
# regression test for GH8099, GH9839
1084+
ds = xr.Dataset({"x": ("a", np.arange(4))}, coords={"a": (np.arange(4) - 1.5)})
1085+
t = xr.DataArray(
1086+
np.random.randn(6).reshape((2, 3)) * 0.5,
1087+
dims=["r", "s"],
1088+
coords={"r": np.arange(2) - 0.5, "s": np.arange(3) - 1},
1089+
)
1090+
ds["m"] = ds.x > 1
1091+
1092+
actual = ds.interp(a=t, method="linear")
1093+
# with numeric only
1094+
expected = ds[["x"]].interp(a=t, method="linear")
1095+
assert_identical(actual[["x"]], expected)

0 commit comments

Comments
 (0)