diff --git a/pyaerocom/helpers.py b/pyaerocom/helpers.py index ef663d44c..16b72b21b 100644 --- a/pyaerocom/helpers.py +++ b/pyaerocom/helpers.py @@ -945,14 +945,14 @@ def merge_station_data( return merged -def _get_pandas_freq_and_loffset(freq): +def _get_pandas_freq_and_offset(freq: str) -> tuple[str, pd.Timedelta | None]: """Helper to convert resampling info""" if freq in TS_TYPE_TO_PANDAS_FREQ: freq = TS_TYPE_TO_PANDAS_FREQ[freq] - loffset = None + offset = None if freq in PANDAS_RESAMPLE_OFFSETS: - loffset = PANDAS_RESAMPLE_OFFSETS[freq] - return (freq, loffset) + offset = PANDAS_RESAMPLE_OFFSETS[freq] + return (freq, offset) def make_datetime_index(start, stop, freq): @@ -983,10 +983,10 @@ def make_datetime_index(start, stop, freq): if not isinstance(stop, pd.Timestamp): stop = to_pandas_timestamp(stop) - freq, loffset = _get_pandas_freq_and_loffset(freq) + freq, offset = _get_pandas_freq_and_offset(freq) idx = pd.date_range(start=start, end=stop, freq=freq) - if loffset is not None: - idx = idx + pd.Timedelta(loffset) + if offset is not None: + idx = idx + offset return idx @@ -1096,7 +1096,7 @@ def resample_timeseries(ts, freq, how=None, min_num_obs=None): p = int(how.split("percentile")[0]) how = lambda x: np.nanpercentile(x, p) # noqa: E731 - freq, loffset = _get_pandas_freq_and_loffset(freq) + freq, offset = _get_pandas_freq_and_offset(freq) resampler = ts.resample(freq) data = resampler.agg(how) @@ -1106,8 +1106,8 @@ def resample_timeseries(ts, freq, how=None, min_num_obs=None): invalid = numobs < min_num_obs if np.any(invalid): data.values[invalid] = np.nan - if loffset is not None: - data.index = data.index + pd.Timedelta(loffset) + if offset is not None: + data.index = data.index + offset return data @@ -1165,8 +1165,8 @@ def resample_time_dataarray(arr, freq, how=None, min_num_obs=None): if min_num_obs is not None: invalid = arr.resample(time=pd_freq).count(dim="time") < min_num_obs - freq, loffset = _get_pandas_freq_and_loffset(freq) - resampler = arr.resample(time=pd_freq, loffset=loffset) + freq, offset = _get_pandas_freq_and_offset(freq) + resampler = arr.resample(time=pd_freq, offset=offset) try: aggfun = getattr(resampler, how) except AttributeError: diff --git a/pyaerocom/stats/mda8/mda8.py b/pyaerocom/stats/mda8/mda8.py index 5fe6daf1e..54b031c34 100644 --- a/pyaerocom/stats/mda8/mda8.py +++ b/pyaerocom/stats/mda8/mda8.py @@ -104,9 +104,6 @@ def _rolling_average_8hr(arr: xr.DataArray) -> xr.DataArray: def _daily_max(arr: xr.DataArray) -> xr.DataArray: - # TODO: Base is deprecated, and using offset="1h" is the proper way to do this. - # However this currently breaks the old-dependencies test in CI. Should be - # changed in the future. - return arr.resample(time="24H", base=1).reduce( + return arr.resample(time="24H", offset="1h").reduce( lambda x, axis: np.apply_along_axis(min_periods_max, 1, x, min_periods=18) ) diff --git a/pyaerocom/time_config.py b/pyaerocom/time_config.py index 00a110786..107060f00 100644 --- a/pyaerocom/time_config.py +++ b/pyaerocom/time_config.py @@ -4,6 +4,7 @@ from datetime import datetime +import pandas as pd from iris import coord_categorisation TS_TYPES = ["minutely", "hourly", "daily", "weekly", "monthly", "yearly", "native", "coarsest"] @@ -40,8 +41,12 @@ "season": "Q", "yearly": "YS", } - -PANDAS_RESAMPLE_OFFSETS = {"YS": "181D", "MS": "14D", "D": "12h", "h": "30min"} +PANDAS_RESAMPLE_OFFSETS = { + "YS": pd.Timedelta(181, "d"), + "MS": pd.Timedelta(14, "d"), + "D": pd.Timedelta(12, "h"), + "h": pd.Timedelta(30, "m"), +} PANDAS_FREQ_TO_TS_TYPE = {v: k for k, v in TS_TYPE_TO_PANDAS_FREQ.items()} diff --git a/pyaerocom_env.yml b/pyaerocom_env.yml index c92368886..0cbdee7c0 100644 --- a/pyaerocom_env.yml +++ b/pyaerocom_env.yml @@ -4,7 +4,7 @@ channels: - conda-forge dependencies: - iris >=3.8.1 - - xarray >=2022.10.0, <2024.7.0 + - xarray >=2022.12.0 - cartopy >=0.21.1 - matplotlib-base >=3.7.1 - scipy >=1.10.1 diff --git a/pyproject.toml b/pyproject.toml index 8dc25f591..7fb10fa2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ requires-python = ">=3.10" dependencies = [ "aerovaldb@git+https://github.com/metno/aerovaldb.git@v0.0.14", "scitools-iris>=3.8.1", - "xarray>=2022.10.0, <2024.7.0", + "xarray>=2022.12.0", "cartopy>=0.21.1", "matplotlib>=3.7.1", "scipy>=1.10.1", @@ -230,7 +230,7 @@ deps = pydantic ==2.7.1; python_version < "3.11" pyaro == 0.0.10; python_version < "3.11" pooch ==1.7.0; python_version < "3.11" - xarray ==2022.10.0; python_version < "3.11" + xarray ==2022.12.0; python_version < "3.11" pandas ==1.5.3; python_version < "3.11" [testenv:lint] diff --git a/tests/test_helpers.py b/tests/test_helpers.py index ac69ec283..db80db874 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -90,9 +90,9 @@ def test_merge_station_data_error(statlist, use, exception, error): assert str(e.value).startswith(error) -def test__get_pandas_freq_and_loffset(): - val = helpers._get_pandas_freq_and_loffset("monthly") - assert val == ("MS", "14D") +def test__get_pandas_freq_and_offset(): + val = helpers._get_pandas_freq_and_offset("monthly") + assert val == ("MS", pd.Timedelta(14, "d")) @pytest.fixture(scope="module")