diff --git a/CHANGELOG.md b/CHANGELOG.md index 829c027c527..4920d8a6e5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Added support for `TimedeltaIndex.mean` method. - Added support for some cases of aggregating `Timedelta` columns on `axis=0` with `agg` or `aggregate`. - Added support for `by`, `left_by`, `right_by`, `left_index`, and `right_index` for `pd.merge_asof`. +- Added support for `Resampler.asfreq`. #### Bug Fixes diff --git a/docs/source/modin/supported/resampling_supported.rst b/docs/source/modin/supported/resampling_supported.rst index f00cba01767..7c00f30d452 100644 --- a/docs/source/modin/supported/resampling_supported.rst +++ b/docs/source/modin/supported/resampling_supported.rst @@ -44,7 +44,7 @@ Upsampling +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | Resampler method | Snowpark implemented? (Y/N/P/D) | Missing parameters | Notes for current implementation | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ -| ``asfreq`` | N | | | +| ``asfreq`` | P | ``fill_value`` | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ | ``bfill`` | P | ``limit`` | | +-----------------------------+---------------------------------+----------------------------------+----------------------------------------------------+ diff --git a/src/snowflake/snowpark/modin/pandas/resample.py b/src/snowflake/snowpark/modin/pandas/resample.py index 740072ae2f8..0501d5e042e 100644 --- a/src/snowflake/snowpark/modin/pandas/resample.py +++ b/src/snowflake/snowpark/modin/pandas/resample.py @@ -280,8 +280,24 @@ def fillna(self, method: str, limit: Optional[int] = None): ) return getattr(self, method)(limit=limit) - def asfreq(self, fill_value: Optional[Any] = None): # pragma: no cover - self._method_not_implemented("asfreq") + def asfreq(self, fill_value: Optional[Any] = None): + is_series = not self._dataframe._is_dataframe + + if fill_value is not None: + # TODO: SNOW-1660802: Implement `fill_value` parameter once `GroupBy.fillna` is supported + ErrorMessage.not_implemented( + "Parameter fill_value of resample.asfreq has not been implemented." + ) + + return self._dataframe.__constructor__( + query_compiler=self._query_compiler.resample( + self.resample_kwargs, + "first", + (), + {}, + is_series, + ) + ) def interpolate( self, diff --git a/src/snowflake/snowpark/modin/plugin/docstrings/resample.py b/src/snowflake/snowpark/modin/plugin/docstrings/resample.py index 05627cfbc31..3bf90e5de67 100644 --- a/src/snowflake/snowpark/modin/plugin/docstrings/resample.py +++ b/src/snowflake/snowpark/modin/plugin/docstrings/resample.py @@ -406,7 +406,44 @@ def fillna(): """ def asfreq(): - pass + """ + Return the values at the new freq, essentially a reindex. + + Parameters + ---------- + fill_value : scalar, optional + This parameter is not supported and will raise NotImplementedError. + + Returns + ------- + :class:`~modin.pandas.Series` or :class:`~modin.pandas.DataFrame` + Values at the specified freq. + + See Also + -------- + Series.asfreq: Convert TimeSeries to specified frequency. + DataFrame.asfreq: Convert TimeSeries to specified frequency. + + Examples + -------- + >>> s = pd.Series([1, 2, 3], index=pd.date_range('20180101', periods=3, freq='h')) + >>> s + 2018-01-01 00:00:00 1 + 2018-01-01 01:00:00 2 + 2018-01-01 02:00:00 3 + Freq: None, dtype: int64 + >>> s.resample("30min").asfreq() + 2018-01-01 00:00:00 1.0 + 2018-01-01 00:30:00 NaN + 2018-01-01 01:00:00 2.0 + 2018-01-01 01:30:00 NaN + 2018-01-01 02:00:00 3.0 + Freq: None, dtype: float64 + >>> s.resample("2h").asfreq() + 2018-01-01 00:00:00 1 + 2018-01-01 02:00:00 3 + Freq: None, dtype: int64 + """ def interpolate(): pass diff --git a/tests/integ/modin/resample/test_resample_asfreq.py b/tests/integ/modin/resample/test_resample_asfreq.py index 50e9646a4cc..b3e69993e5e 100644 --- a/tests/integ/modin/resample/test_resample_asfreq.py +++ b/tests/integ/modin/resample/test_resample_asfreq.py @@ -44,6 +44,19 @@ def test_asfreq_ffill(): ) +@sql_count_checker(query_count=3, join_count=1) +@pytest.mark.parametrize("freq", ["3min", "30S"]) +def test_resampler_asfreq(freq): + eval_snowpark_pandas_result( + *create_test_dfs( + {"A": np.random.randn(15)}, + index=native_pd.date_range("2020-01-01", periods=15, freq="1min"), + ), + lambda df: df.resample(freq).asfreq(), + check_freq=False, + ) + + @sql_count_checker(query_count=0) def test_asfreq_negative(): snow_df = pd.DataFrame( @@ -56,3 +69,5 @@ def test_asfreq_negative(): snow_df.asfreq(freq="5s", method="ffill", normalize=True) with pytest.raises(NotImplementedError): snow_df.asfreq(freq="5s", method="ffill", fill_value=2) + with pytest.raises(NotImplementedError): + snow_df.resample("5s").asfreq(fill_value=2)