From 74829ccd4b709c012310744b4b3198637becad3a Mon Sep 17 00:00:00 2001 From: Bart Schilperoort Date: Tue, 10 Sep 2024 14:02:14 +0200 Subject: [PATCH] Implement new "most common" regridder. --- README.md | 2 +- docs/getting_started.rst | 2 +- docs/notebooks/demos/demo_most_common.ipynb | 785 +++++++++++++++++++- src/xarray_regrid/methods/_shared.py | 93 +++ src/xarray_regrid/methods/flox_reduce.py | 145 ++++ src/xarray_regrid/methods/most_common.py | 255 ------- src/xarray_regrid/regrid.py | 36 +- tests/test_most_common.py | 42 +- 8 files changed, 1058 insertions(+), 302 deletions(-) create mode 100644 src/xarray_regrid/methods/_shared.py create mode 100644 src/xarray_regrid/methods/flox_reduce.py delete mode 100644 src/xarray_regrid/methods/most_common.py diff --git a/README.md b/README.md index 4b5b41e..1efe67b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ With xarray-regrid it is possible to regrid between two rectilinear grids. The f - Cubic - "Most common value" (zonal statistics) -All regridding methods, except for the "most common value" can operate lazily on [Dask arrays](https://docs.xarray.dev/en/latest/user-guide/dask.html). +All regridding methods can operate lazily on [Dask arrays](https://docs.xarray.dev/en/latest/user-guide/dask.html). Note that "Most common value" is designed to regrid categorical data to a coarse resolution. For regridding categorical data to a finer resolution, please use "nearest-neighbor" regridder. diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 33b0f25..c5299f9 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -34,5 +34,5 @@ Multiple regridding methods are available: * `conservative regridding `_ (``.regrid.conservative``) Additionally, a zonal statistics `method to compute the most common value `_ -is available (``.regrid.most_common``). +is available for DataArrays (``.regrid.most_common``). This can be used to upscale very fine categorical data to a more course resolution. diff --git a/docs/notebooks/demos/demo_most_common.ipynb b/docs/notebooks/demos/demo_most_common.ipynb index a322d1a..6533f14 100644 --- a/docs/notebooks/demos/demo_most_common.ipynb +++ b/docs/notebooks/demos/demo_most_common.ipynb @@ -39,84 +39,817 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Next twe need a high resolution dataset to regrid. We used the LCCS land cover data which is available from the [Climate Data Store](https://cds.climate.copernicus.eu/cdsapp#!/dataset/satellite-land-cover).\n", + "Next we need a high resolution dataset to regrid. We used the LCCS land cover data which is available from the [Climate Data Store](https://cds.climate.copernicus.eu/cdsapp#!/dataset/satellite-land-cover).\n", "\n", - "We will also define our target grid:" + "Note the data is loaded in as a dask arrays, allowing for lazy computation." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'lccs_class' (time: 1, latitude: 64800, longitude: 129600)> Size: 8GB\n",
+       "dask.array<getitem, shape=(1, 64800, 129600), dtype=uint8, chunksize=(1, 9257, 10125), chunktype=numpy.ndarray>\n",
+       "Coordinates:\n",
+       "  * latitude   (latitude) float64 518kB -90.0 -90.0 -89.99 ... 89.99 90.0 90.0\n",
+       "  * longitude  (longitude) float64 1MB -180.0 -180.0 -180.0 ... 180.0 180.0\n",
+       "  * time       (time) datetime64[ns] 8B 2020-01-01\n",
+       "Attributes:\n",
+       "    standard_name:        land_cover_lccs\n",
+       "    flag_colors:          #ffff64 #ffff64 #ffff00 #aaf0f0 #dcf064 #c8c864 #00...\n",
+       "    long_name:            Land cover class defined in LCCS\n",
+       "    valid_min:            1\n",
+       "    valid_max:            220\n",
+       "    ancillary_variables:  processed_flag current_pixel_state observation_coun...\n",
+       "    flag_meanings:        no_data cropland_rainfed cropland_rainfed_herbaceou...\n",
+       "    flag_values:          [  0  10  11  12  20  30  40  50  60  61  62  70  7...
" + ], + "text/plain": [ + " Size: 8GB\n", + "dask.array\n", + "Coordinates:\n", + " * latitude (latitude) float64 518kB -90.0 -90.0 -89.99 ... 89.99 90.0 90.0\n", + " * longitude (longitude) float64 1MB -180.0 -180.0 -180.0 ... 180.0 180.0\n", + " * time (time) datetime64[ns] 8B 2020-01-01\n", + "Attributes:\n", + " standard_name: land_cover_lccs\n", + " flag_colors: #ffff64 #ffff64 #ffff00 #aaf0f0 #dcf064 #c8c864 #00...\n", + " long_name: Land cover class defined in LCCS\n", + " valid_min: 1\n", + " valid_max: 220\n", + " ancillary_variables: processed_flag current_pixel_state observation_coun...\n", + " flag_meanings: no_data cropland_rainfed cropland_rainfed_herbaceou...\n", + " flag_values: [ 0 10 11 12 20 30 40 50 60 61 62 70 7..." + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ds = xr.open_dataset(\n", - " \"../ESACCI-LC-L4-LCCS-Map-300m-P1Y-2013-v2.0.7cds.nc\",\n", - " chunks={\"lat\": 2000, \"lon\": 2000},\n", + " \"/data/C3S-LC-L4-LCCS-Map-300m-P1Y-2020-v2.1.1.nc\",\n", + " chunks=\"auto\",\n", ")\n", "\n", - "ds = ds[[\"lccs_class\"]] # Only take the class variable.\n", - "ds = ds.sortby([\"lat\", \"lon\"])\n", - "ds = ds.rename({\"lat\": \"latitude\", \"lon\": \"longitude\"})\n", - "\n", - "from xarray_regrid import Grid, create_regridding_dataset\n", + "da = ds[\"lccs_class\"] # Only take the class variable.\n", + "da = da.sortby([\"lat\", \"lon\"])\n", + "da = da.rename({\"lat\": \"latitude\", \"lon\": \"longitude\"})\n", + "da" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We will also define our target grid:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from xarray_regrid import Grid\n", "\n", - "new_grid = Grid(\n", + "target_dataset = Grid(\n", " north=90,\n", " east=90,\n", " south=0,\n", " west=0,\n", " resolution_lat=1,\n", " resolution_lon=1,\n", - ")\n", - "target_dataset = create_regridding_dataset(new_grid)" + ").create_regridding_dataset()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Using `regrid.most_common` you can regrid the data.\n", - "\n", - "Currently the computation can not be done fully lazily, however a workaround that splits the problem into chunks and combines the solution is available. This is enabled using the \"max_mem\" keyword argument.\n", + "The default chunks are a bit large for this regridding operation, so we need to rechunk before continuing to avoid memory issues: " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Array Chunk
Bytes 7.82 GiB 15.64 MiB
Shape (1, 64800, 129600) (1, 4050, 4050)
Dask graph 512 chunks in 5 graph layers
Data type uint8 numpy.ndarray
\n", + "
\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n", + "\n", + " \n", + " 129600\n", + " 64800\n", + " 1\n", + "\n", + "
" + ], + "text/plain": [ + "dask.array" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "da = da.chunk({\"time\": -1, \"latitude\": 4050, \"longitude\": 4050})\n", + "da.data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using `regrid.most_common` you can now regrid the data. This is currently only implemented for `DataArray`s, not `xr.Dataset`.\n", "\n", - "Note that the maximum memory limits the size of the regridding routine (in bytes), not of the input/output data, so total memory use can be higher." + "Note that we have to provide the expected groups (i.e. unique labels) in the data. This dataset already conventiently stores these in the attributes." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "ds_regrid = ds.regrid.most_common(target_dataset, time_dim=\"time\", max_mem=1e9)" + "da_regrid = da.regrid.most_common(\n", + " target_dataset, expected_groups=da.attrs[\"flag_values\"], time_dim=\"time\"\n", + ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "After computation, we can plot the solution:" + "When we call `.plot` on the DataArray, computation will begin." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 4, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -126,7 +859,7 @@ } ], "source": [ - "ds_regrid[\"lccs_class\"].plot(x=\"longitude\")" + "da_regrid.plot(x=\"longitude\")" ] }, { @@ -153,7 +886,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.0" + "version": "3.12.0" }, "orig_nbformat": 4 }, diff --git a/src/xarray_regrid/methods/_shared.py b/src/xarray_regrid/methods/_shared.py new file mode 100644 index 0000000..cc629a0 --- /dev/null +++ b/src/xarray_regrid/methods/_shared.py @@ -0,0 +1,93 @@ +"""Utility functions shared between methods.""" + +from typing import overload + +import numpy as np +import pandas as pd +import xarray as xr + + +def construct_intervals(coord: np.ndarray) -> pd.IntervalIndex: + """Create pandas.intervals with given coordinates.""" + step_size = np.median(np.diff(coord, n=1)) + breaks = np.append(coord, coord[-1] + step_size) - step_size / 2 + + # Note: closed="both" triggers an `NotImplementedError` + return pd.IntervalIndex.from_breaks(breaks, closed="left") + + +@overload +def restore_properties( + result: xr.DataArray, + original_data: xr.DataArray | xr.Dataset, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.DataArray: ... + + +@overload +def restore_properties( + result: xr.Dataset, + original_data: xr.DataArray | xr.Dataset, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.Dataset: ... + + +def restore_properties( + result: xr.DataArray | xr.Dataset, + original_data: xr.DataArray | xr.Dataset, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.DataArray | xr.Dataset: + """Restore coord names, copy values and attributes of target, & add NaN padding.""" + result.attrs = original_data.attrs + + result = result.rename({f"{coord}_bins": coord for coord in coords}) + for coord in coords: + result[coord] = target_ds[coord] + result[coord].attrs = target_ds[coord].attrs + + # Replace zeros outside of original data grid with NaNs + uncovered_target_grid = (target_ds[coord] <= original_data[coord].max()) & ( + target_ds[coord] >= original_data[coord].min() + ) + result = result.where(uncovered_target_grid) + + return result.transpose(*original_data.dims) + + +@overload +def reduce_data_to_new_domain( + data: xr.DataArray, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.DataArray: ... + + +@overload +def reduce_data_to_new_domain( + data: xr.Dataset, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.Dataset: ... + + +def reduce_data_to_new_domain( + data: xr.DataArray | xr.Dataset, + target_ds: xr.Dataset, + coords: list[str], +) -> xr.DataArray | xr.Dataset: + """Slice the input data to bounds of the target dataset, to reduce computations.""" + data = data.sortby(list(coords)) + for coord in coords: + coord_res = np.median(np.diff(target_ds[coord].to_numpy(), 1)) + data = data.sel( + { + coord: slice( + target_ds[coord].min().to_numpy() - coord_res, + target_ds[coord].max().to_numpy() + coord_res, + ) + } + ) + return data diff --git a/src/xarray_regrid/methods/flox_reduce.py b/src/xarray_regrid/methods/flox_reduce.py new file mode 100644 index 0000000..2f484bc --- /dev/null +++ b/src/xarray_regrid/methods/flox_reduce.py @@ -0,0 +1,145 @@ +"""Implementation of flox reduction based regridding methods.""" + +import flox.xarray +import numpy as np +import pandas as pd +import xarray as xr + +from xarray_regrid import utils +from xarray_regrid.methods._shared import ( + construct_intervals, + reduce_data_to_new_domain, + restore_properties, +) + + +def statistic_reduce( + data: xr.Dataset, + target_ds: xr.Dataset, + time_dim: str, + method: str, + skipna: bool = False, +) -> xr.Dataset: + """Upsampling of data using statistical methods (e.g. the mean or variance). + + We use flox Aggregations to perform a "groupby" over multiple dimensions, which we + reduce using the specified method. + https://flox.readthedocs.io/en/latest/aggregations.html + + Args: + data: Input dataset. + target_ds: Dataset which coordinates the input dataset should be regrid to. + time_dim: Name of the time dimension. Defaults to "time". Use `None` to force + regridding over the time dimension. + method: One of the following reduction methods: "sum", "mean", "var", "std". + skipna: If NaN values should be ignored. + + Returns: + xarray.dataset with regridded land cover categorical data. + """ + valid_methods = ["sum", "mean", "var", "std"] + if method not in valid_methods: + msg = f"Invalid method. Please choose from '{valid_methods}'." + raise ValueError(msg) + + if skipna: + method = "nan" + method + + coords = utils.common_coords(data, target_ds, remove_coord=time_dim) + + bounds = tuple(construct_intervals(target_ds[coord].to_numpy()) for coord in coords) + + data = reduce_data_to_new_domain(data, target_ds, coords) + + result: xr.Dataset = flox.xarray.xarray_reduce( + data.compute(), + *coords, + func=method, + expected_groups=bounds, + ) + + return restore_properties(result, data, target_ds, coords) + + +def find_matching_int_dtype( + a: np.ndarray, +) -> type[np.signedinteger] | type[np.unsignedinteger]: + """Find the smallest integer datatype that can cover the given array.""" + # Integer types in increasing memory use + int_types: list[type[np.signedinteger] | type[np.unsignedinteger]] = [ + np.int8, + np.uint8, + np.int16, + np.uint16, + np.int32, + np.uint32, + ] + for dtype in int_types: + if (a.max() <= np.iinfo(dtype).max) and (a.min() >= np.iinfo(dtype).min): + return dtype + return np.int64 + + +def get_most_common_value( + data: xr.DataArray, + target_ds: xr.Dataset, + expected_groups: np.ndarray, + time_dim: str | None = "time", + inverse: bool = False, +) -> xr.DataArray: + """Upsample the input data using a "most common label" (mode) approach. + + Args: + data: Input DataArray, with an integer data type. If your data does not consist + of integer type values, you will have to encode them to integer types. + target_ds: Dataset which coordinates the input dataset should be regrid to. + expected_groups: Numpy array containing all labels expected to be in the input + data. For example, `np.array([0, 2, 4])`, if the data only contains the + values 0, 2 and 4. + time_dim: Name of the time dimension. Defaults to "time". Use `None` to force + regridding over the time dimension. + inverse: Find the least-common-value (anti-mode). + + Raises: + ValueError: if the input data is not of an integer dtype. + + Returns: + xarray.DataArray with regridded categorical data. + """ + array_name = data.name if data.name is not None else "DATA_NAME" + + # Must be categorical data (integers) + if not np.issubdtype(data.dtype, np.integer): + msg = ( + "Your input data has to be of an integer datatype for this method.\n" + f" instead, your data is of type '{data.dtype}'." + "You can convert the data with:\n `dataset.astype(int)`." + ) + raise ValueError(msg) + + coords = utils.common_coords(data, target_ds, remove_coord=time_dim) + target_ds_sorted = target_ds.sortby(list(coords)) + + bounds = tuple( + construct_intervals(target_ds_sorted[coord].to_numpy()) for coord in coords + ) + + data = reduce_data_to_new_domain(data, target_ds_sorted, coords) + + # Reduce memory usage by picking the most minimal integer type + dtype = find_matching_int_dtype(expected_groups) + + result: xr.DataArray = flox.xarray.xarray_reduce( + xr.ones_like(data, dtype=bool), + data.astype(dtype), # important, needs to be int + *coords, + dim=coords, + func="count", + expected_groups=(pd.Index(expected_groups.astype(dtype)), *bounds), + fill_value=-1, + ) + result = result.idxmax(array_name) if not inverse else result.idxmin(array_name) + + result = restore_properties(result, data, target_ds_sorted, coords) + result = result.reindex_like(target_ds, copy=False) + return result diff --git a/src/xarray_regrid/methods/most_common.py b/src/xarray_regrid/methods/most_common.py deleted file mode 100644 index e0407f7..0000000 --- a/src/xarray_regrid/methods/most_common.py +++ /dev/null @@ -1,255 +0,0 @@ -"""Implementation of the "most common value" regridding method.""" - -from itertools import product -from typing import Any, overload - -import flox.xarray -import numpy as np -import numpy_groupies as npg # type: ignore -import pandas as pd -import xarray as xr -from flox import Aggregation - -from xarray_regrid import utils - - -@overload -def most_common_wrapper( - data: xr.DataArray, - target_ds: xr.Dataset, - time_dim: str = "", - max_mem: int | None = None, -) -> xr.DataArray: ... - - -@overload -def most_common_wrapper( - data: xr.Dataset, - target_ds: xr.Dataset, - time_dim: str = "", - max_mem: int | None = None, -) -> xr.Dataset: ... - - -def most_common_wrapper( - data: xr.DataArray | xr.Dataset, - target_ds: xr.Dataset, - time_dim: str = "", - max_mem: int | None = None, -) -> xr.DataArray | xr.Dataset: - """Wrapper for the most common regridder, allowing for analyzing larger datasets. - - Args: - data: Input dataset. - target_ds: Dataset which coordinates the input dataset should be regrid to. - time_dim: Name of the time dimension, as the regridders do not regrid over time. - Defaults to "time". - max_mem: (Approximate) maximum memory in bytes that the regridding routines can - use. Note that this is not the total memory consumption and does not include - the size of the final dataset. - If this kwargs is used, the regridding will be split up into more manageable - chunks, and combined for the final dataset. - - Returns: - xarray.dataset with regridded categorical data. - """ - da_name = None - if isinstance(data, xr.DataArray): - da_name = "da" if data.name is None else data.name - data = data.to_dataset(name=da_name) - - coords = utils.common_coords(data, target_ds) - target_ds_sorted = target_ds.sortby(list(coords)) - coord_size = [data[coord].size for coord in coords] - mem_usage = np.prod(coord_size) * np.zeros((1,), dtype=np.int64).itemsize - - if max_mem is not None and mem_usage > max_mem: - result = split_combine_most_common( - data=data, target_ds=target_ds_sorted, time_dim=time_dim, max_mem=max_mem - ) - else: - result = most_common(data=data, target_ds=target_ds_sorted, time_dim=time_dim) - - result = result.reindex_like(target_ds, copy=False) - - if da_name is not None: - return result[da_name] - else: - return result - - -def split_combine_most_common( - data: xr.Dataset, target_ds: xr.Dataset, time_dim: str, max_mem: int = int(1e9) -) -> xr.Dataset: - """Use a split-combine strategy to reduce the memory use of the most_common regrid. - - Args: - data: Input dataset. - target_ds: Dataset which coordinates the input dataset should be regrid to. - time_dim: Name of the time dimension, as the regridders do not regrid over time. - Defaults to "time". - max_mem: (Approximate) maximum memory in bytes that the regridding routines can - use. Note that this is not the total memory consumption and does not include - the size of the final dataset. Defaults to 1e9 (1 GB). - - Returns: - xarray.dataset with regridded categorical data. - """ - coords = utils.common_coords(data, target_ds, remove_coord=time_dim) - max_datapoints = max_mem // 8 # ~8 bytes per item. - max_source_coord_size = max_datapoints ** (1 / len(coords)) - size_ratios = { - coord: ( - np.median(np.diff(data[coord].to_numpy(), 1)) - / np.median(np.diff(target_ds[coord].to_numpy(), 1)) - ) - for coord in coords - } - max_coord_size = { - coord: int(size_ratios[coord] * max_source_coord_size) for coord in coords - } - - blocks = { - coord: np.arange(0, target_ds[coord].size, max_coord_size[coord]) - for coord in coords - } - - subsets = [] - for vals in product(*blocks.values()): - isel = {} - for coord, val in zip(blocks.keys(), vals, strict=True): - isel[coord] = slice(val, val + max_coord_size[coord]) - subsets.append(most_common(data, target_ds.isel(isel), time_dim=time_dim)) - - return xr.merge(subsets) - - -def most_common(data: xr.Dataset, target_ds: xr.Dataset, time_dim: str) -> xr.Dataset: - """Upsampling of data with a "most common label" approach. - - The implementation includes two steps: - - "groupby" coordinates - - select most common label - - We use flox to perform "groupby" multiple dimensions. Here is an example: - https://flox.readthedocs.io/en/latest/intro.html#histogramming-binning-by-multiple-variables - - To embed our customized function for most common label selection, we need to - create our `flox.Aggregation`, for instance: - https://flox.readthedocs.io/en/latest/aggregations.html - - `flox.Aggregation` function works with `numpy_groupies.aggregate_numpy.aggregate - API. Therefore this function also depends on `numpy_groupies`. For more information, - check the following example: - https://flox.readthedocs.io/en/latest/user-stories/custom-aggregations.html - - Args: - data: Input dataset. - target_ds: Dataset which coordinates the input dataset should be regrid to. - - Returns: - xarray.dataset with regridded land cover categorical data. - """ - dim_order = data.dims - coords = utils.common_coords(data, target_ds, remove_coord=time_dim) - coord_attrs = {coord: data[coord].attrs for coord in target_ds.coords} - - bounds = tuple( - _construct_intervals(target_ds[coord].to_numpy()) for coord in coords - ) - - # Slice the input data to the bounds of the target dataset - data = data.sortby(list(coords)) - for coord in coords: - coord_res = np.median(np.diff(target_ds[coord].to_numpy(), 1)) - data = data.sel( - { - coord: slice( - target_ds[coord].min().to_numpy() - coord_res, - target_ds[coord].max().to_numpy() + coord_res, - ) - } - ) - - most_common = Aggregation( - name="most_common", - numpy=_custom_grouped_reduction, # type: ignore - chunk=None, - combine=None, - ) - - ds_regrid: xr.Dataset = flox.xarray.xarray_reduce( - data.compute(), - *coords, - func=most_common, - expected_groups=bounds, - ) - - ds_regrid = ds_regrid.rename({f"{coord}_bins": coord for coord in coords}) - for coord in coords: - ds_regrid[coord] = target_ds[coord] - - # Replace zeros outside of original data grid with NaNs - uncovered_target_grid = (target_ds[coord] <= data[coord].max()) & ( - target_ds[coord] >= data[coord].min() - ) - ds_regrid = ds_regrid.where(uncovered_target_grid) - - ds_regrid[coord].attrs = coord_attrs[coord] - - return ds_regrid.transpose(*dim_order) - - -def _construct_intervals(coord: np.ndarray) -> pd.IntervalIndex: - """Create pandas.intervals with given coordinates.""" - step_size = np.median(np.diff(coord, n=1)) - breaks = np.append(coord, coord[-1] + step_size) - step_size / 2 - - # Note: closed="both" triggers an `NotImplementedError` - return pd.IntervalIndex.from_breaks(breaks, closed="left") - - -def _most_common_label(neighbors: np.ndarray) -> np.ndarray: - """Find the most common label in a neighborhood. - - Note that if more than one labels have the same frequency which is the highest, - then the first label in the list will be picked. - """ - unique_labels, counts = np.unique(neighbors, return_counts=True) - return unique_labels[np.argmax(counts)] # type: ignore - - -def _custom_grouped_reduction( - group_idx: np.ndarray, - array: np.ndarray, - *, - axis: int = -1, - size: int | None = None, - fill_value: Any = None, - dtype: Any = None, -) -> np.ndarray: - """Custom grouped reduction for flox.Aggregation to get most common label. - - Args: - group_idx : integer codes for group labels (1D) - array : values to reduce (nD) - axis : axis of array along which to reduce. - Requires array.shape[axis] == len(group_idx) - size : expected number of groups. If none, - output.shape[-1] == number of uniques in group_idx - fill_value : fill_value for when number groups in group_idx is less than size - dtype : dtype of output - - Returns: - np.ndarray with array.shape[-1] == size, containing a single value per group - """ - agg: np.ndarray = npg.aggregate_numpy.aggregate( - group_idx, - array, - func=_most_common_label, - axis=axis, - size=size, - fill_value=fill_value, - dtype=dtype, - ) - return agg diff --git a/src/xarray_regrid/regrid.py b/src/xarray_regrid/regrid.py index e91348a..b6709ae 100644 --- a/src/xarray_regrid/regrid.py +++ b/src/xarray_regrid/regrid.py @@ -1,6 +1,7 @@ +import numpy as np import xarray as xr -from xarray_regrid.methods import conservative, interp, most_common +from xarray_regrid.methods import conservative, flox_reduce, interp @xr.register_dataarray_accessor("regrid") @@ -111,9 +112,10 @@ def conservative( def most_common( self, ds_target_grid: xr.Dataset, + expected_groups: np.ndarray, time_dim: str = "time", - max_mem: int = int(1e9), - ) -> xr.DataArray | xr.Dataset: + inverse: bool = False, + ) -> xr.DataArray: """Regrid by taking the most common value within the new grid cells. To be used for regridding data to a much coarser resolution, not for regridding @@ -125,17 +127,33 @@ def most_common( Args: ds_target_grid: Target grid dataset - time_dim: Name of the time dimension. Defaults to "time". - max_mem: (Approximate) maximum memory in bytes that the regridding routine - can use. Note that this is not the total memory consumption and does not - include the size of the final dataset. Defaults to 1e9 (1 GB). + expected_groups: Numpy array containing all labels expected to be in the + input data. For example, `np.array([0, 2, 4])`, if the data only + contains the values 0, 2 and 4. + time_dim: Name of the time dimension. Defaults to "time". Use `None` to + force regridding over the time dimension. + inverse: Find the least-common-value (anti-mode). Returns: Regridded data. """ ds_target_grid = validate_input(self._obj, ds_target_grid, time_dim) - return most_common.most_common_wrapper( - self._obj, ds_target_grid, time_dim, max_mem + + if isinstance(self._obj, xr.Dataset): + msg = ( + "The 'most common value' regridder is not implemented for\n", + "xarray.Dataset, as it requires specifying the expected labels.\n" + "Please select only a single variable (as DataArray),\n" + " and regrid it separately.", + ) + raise ValueError(msg) + + return flox_reduce.get_most_common_value( + self._obj, + ds_target_grid, + expected_groups, + time_dim, + inverse, ) diff --git a/tests/test_most_common.py b/tests/test_most_common.py index ec05221..6d275e9 100644 --- a/tests/test_most_common.py +++ b/tests/test_most_common.py @@ -5,6 +5,8 @@ from xarray_regrid import Grid, create_regridding_dataset +EXP_LABELS = np.array([0, 1, 2, 3]) # labels that are in the dummy data + @pytest.fixture def dummy_lc_data(): @@ -26,7 +28,7 @@ def dummy_lc_data(): lat_coords = np.linspace(0, 40, num=11) lon_coords = np.linspace(0, 40, num=11) - return xr.Dataset( + ds = xr.Dataset( data_vars={ "lc": (["longitude", "latitude"], data), }, @@ -36,6 +38,9 @@ def dummy_lc_data(): }, attrs={"test": "not empty"}, ) + ds["longitude"].attrs = {"units": "degrees_east"} + ds["latitude"].attrs = {"units": "degrees_north"} + return ds @pytest.fixture @@ -89,7 +94,10 @@ def test_most_common(dummy_lc_data, dummy_target_grid): }, ) xr.testing.assert_equal( - dummy_lc_data.regrid.most_common(dummy_target_grid)["lc"], + dummy_lc_data["lc"].regrid.most_common( + dummy_target_grid, + expected_groups=EXP_LABELS, + ), expected["lc"], ) @@ -121,41 +129,55 @@ def test_oversized_most_common(dummy_lc_data, oversized_dummy_target_grid): }, ) xr.testing.assert_equal( - dummy_lc_data.regrid.most_common(oversized_dummy_target_grid)["lc"], + dummy_lc_data["lc"].regrid.most_common( + oversized_dummy_target_grid, + expected_groups=EXP_LABELS, + ), expected["lc"], ) def test_attrs_dataarray(dummy_lc_data, dummy_target_grid): dummy_lc_data["lc"].attrs = {"test": "testing"} - da_regrid = dummy_lc_data["lc"].regrid.most_common(dummy_target_grid) + da_regrid = dummy_lc_data["lc"].regrid.most_common( + dummy_target_grid, + expected_groups=EXP_LABELS, + ) assert da_regrid.attrs != {} assert da_regrid.attrs == dummy_lc_data["lc"].attrs - assert da_regrid["longitude"].attrs == dummy_lc_data["longitude"].attrs + assert da_regrid["longitude"].attrs == dummy_target_grid["longitude"].attrs +@pytest.mark.xfail # most common currently does not work for datasets def test_attrs_dataset(dummy_lc_data, dummy_target_grid): ds_regrid = dummy_lc_data.regrid.most_common( dummy_target_grid, + expected_groups=EXP_LABELS, ) assert ds_regrid.attrs != {} assert ds_regrid.attrs == dummy_lc_data.attrs - assert ds_regrid["longitude"].attrs == dummy_lc_data["longitude"].attrs + assert ds_regrid["longitude"].attrs == dummy_target_grid["longitude"].attrs -@pytest.mark.parametrize("dataarray", [True, False]) +@pytest.mark.parametrize("dataarray", [True]) # most common does not work for datasets def test_coord_order_original(dummy_lc_data, dummy_target_grid, dataarray): input_data = dummy_lc_data["lc"] if dataarray else dummy_lc_data - ds_regrid = input_data.regrid.most_common(dummy_target_grid) + ds_regrid = input_data.regrid.most_common( + dummy_target_grid, + expected_groups=EXP_LABELS, + ) assert_array_equal(ds_regrid["latitude"], dummy_target_grid["latitude"]) assert_array_equal(ds_regrid["longitude"], dummy_target_grid["longitude"]) @pytest.mark.parametrize("coord", ["latitude", "longitude"]) -@pytest.mark.parametrize("dataarray", [True, False]) +@pytest.mark.parametrize("dataarray", [True]) # most common does not work for datasets def test_coord_order_reversed(dummy_lc_data, dummy_target_grid, coord, dataarray): input_data = dummy_lc_data["lc"] if dataarray else dummy_lc_data dummy_target_grid[coord] = list(reversed(dummy_target_grid[coord])) - ds_regrid = input_data.regrid.most_common(dummy_target_grid) + ds_regrid = input_data.regrid.most_common( + dummy_target_grid, + expected_groups=EXP_LABELS, + ) assert_array_equal(ds_regrid["latitude"], dummy_target_grid["latitude"]) assert_array_equal(ds_regrid["longitude"], dummy_target_grid["longitude"])