Skip to content

Commit 8411437

Browse files
Fix regrid.stats for unsorted input coords (#58)
* Add test for unsorted coords in stats routine * Copy strategy from conservative routines * Fix type checker, formatting * Update changelog, bump version
1 parent 7e51d9e commit 8411437

File tree

4 files changed

+38
-9
lines changed

4 files changed

+38
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/).
66

7-
## Unreleased
7+
## 0.4.1 (2025-04-08)
88

99
Fixed:
1010
- Attributes are now properly preserved when updating coordinates during pre-formatting for regridding ([#54](https://github.com/xarray-contrib/xarray-regrid/pull/54)).
1111
- Handle datasets with inconsistent chunksizes during pre-formatting ([#57](https://github.com/xarray-contrib/xarray-regrid/pull/57)).
12-
12+
- `regrid.stats` should properly regrid input data even when coordinates are not monotonic ([#58](https://github.com/xarray-contrib/xarray-regrid/pull/58)).
1313

1414
## 0.4.0 (2024-09-26)
1515

src/xarray_regrid/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
"methods",
1010
]
1111

12-
__version__ = "0.4.0"
12+
__version__ = "0.4.1"

src/xarray_regrid/methods/flox_reduce.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,19 @@ def statistic_reduce(
7272
msg = f"Invalid method. Please choose from '{valid_methods}'."
7373
raise ValueError(msg)
7474

75-
coords = utils.common_coords(data, target_ds, remove_coord=time_dim)
76-
target_coords = xr.Dataset(target_ds.coords) # coords target coords for reindexing
77-
sorted_target_coords = target_coords.sortby(coords)
75+
# Make sure the regridding coordinates are sorted
76+
coord_names = utils.common_coords(data, target_ds, remove_coord=time_dim)
77+
sorted_target_coords = xr.Dataset(coords=target_ds.coords)
78+
for coord_name in coord_names:
79+
sorted_target_coords = utils.ensure_monotonic(sorted_target_coords, coord_name)
80+
data = utils.ensure_monotonic(data, coord_name)
81+
coords = {name: sorted_target_coords[name] for name in coord_names}
7882

7983
bounds = tuple(
8084
construct_intervals(sorted_target_coords[coord].to_numpy()) for coord in coords
8185
)
8286

83-
data = reduce_data_to_new_domain(data, sorted_target_coords, coords)
87+
data = reduce_data_to_new_domain(data, sorted_target_coords, coord_names)
8488

8589
result: xr.Dataset = flox.xarray.xarray_reduce(
8690
data,
@@ -91,8 +95,8 @@ def statistic_reduce(
9195
fill_value=fill_value,
9296
)
9397

94-
result = restore_properties(result, data, target_ds, coords, fill_value)
95-
result = result.reindex_like(target_coords, copy=False)
98+
result = restore_properties(result, data, target_ds, coord_names, fill_value)
99+
result = result.reindex_like(sorted_target_coords, copy=False)
96100
return result
97101

98102

tests/test_reduce.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,28 @@ def test_var(dummy_lc_data, dummy_target_grid):
233233
dummy_lc_data["lc"].astype(float).regrid.stat(dummy_target_grid, "var"),
234234
make_expected_ds(expected_data)["lc"],
235235
)
236+
237+
238+
def test_unsorted_coords(dummy_lc_data, dummy_target_grid):
239+
"""Should pass if the input data has coords that are not ordered."""
240+
expected_data = np.array(
241+
[
242+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
243+
[1.0, 0.75, 0.75, 0.0, 0.0, 0.0],
244+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
245+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
246+
[2.25, 0.0, 0.0, 0.0, 0.0, 0.25],
247+
[0.0, 1.6875, 2.25, 0.0, 0.25, 0.0],
248+
]
249+
)
250+
lc_data = dummy_lc_data.copy()
251+
252+
lc_data["scramble_order"] = lc_data["latitude"] * 0 + np.array(
253+
[1, 3, 7, 0, 2, 8, 9, -1, 5, 11, 12]
254+
)
255+
lc_data = lc_data.sortby("scramble_order")
256+
257+
xr.testing.assert_equal(
258+
lc_data["lc"].astype(float).regrid.stat(dummy_target_grid, "var"),
259+
make_expected_ds(expected_data)["lc"],
260+
)

0 commit comments

Comments
 (0)