Repository: dask/dask
Pull request #10789 (2024-01-11 20:08:24)

Address pandas deprecations
- [ ] Closes #xxxx
- [ ] Tests added / passed
- [ ] Passes `pre-commit run --all-files`


github-actions[bot]: ## Unit Test Results
_See [test report](https://dask.github.io/dask/test_report.html) for an extended history of previous test failures. This is useful for diagnosing flaky tests._

0 files   -      15  0 suites   - 15   0s :stopwatch: - 3h 25m 11s
0 tests  -  12 893  0 :white_check_mark:  -  10 936  0 :zzz:  -    932  0 :x:  - 1 025 
0 runs   - 159 776  0 :white_check_mark:  - 142 160  0 :zzz:  - 16 590  0 :x:  - 1 026 

Results for commit d9632330. ± Comparison against base commit efd83759.

[test-results]:data:application/gzip;base64,H4sIAB1LoGUC/1WMywrCMBBFf6Vk7WKSkCH6M5JXYbBtJI+V+O+WWnSyu+dcOC8x05KquE1wmUTt1H4Qe3GN8nbifrTK9732EEbxoOcgZkfLIFIpuZym9K2yyXNf/tcOZrGDeSvkdaW2g4hX1Epr8IgOlXTBWwweICmUBqyUzhirdBTvD3H4F6X7AAAA


Patch:
diff --git a/dask/array/percentile.py b/dask/array/percentile.py
index 11f4e9874..e4ee436a2 100644
--- a/dask/array/percentile.py
+++ b/dask/array/percentile.py
@@ -35,7 +35,15 @@ def _percentile(a, q, method="linear"):
 
     if np.issubdtype(a.dtype, np.datetime64):
         values = a
-        a2 = values.view("i8")
+        if type(a).__name__ in ("Series", "Index"):
+            from dask.dataframe._compat import PANDAS_GE_200
+
+            if PANDAS_GE_200:
+                a2 = values.astype("i8")
+            else:
+                a2 = values.view("i8")
+        else:
+            a2 = values.view("i8")
         result = np_percentile(a2, q, method=method).astype(values.dtype)
         if q[0] == 0:
             # https://github.com/dask/dask/issues/6864
diff --git a/dask/dataframe/core.py b/dask/dataframe/core.py
index e33c04ebf..67e829a52 100644
--- a/dask/dataframe/core.py
+++ b/dask/dataframe/core.py
@@ -8344,7 +8344,7 @@ def maybe_shift_divisions(df, periods, freq):
 
     is_offset = isinstance(freq, pd.DateOffset)
     if is_offset:
-        if freq.is_anchored() or not isinstance(freq, pd.offsets.Tick):
+        if not isinstance(freq, pd.offsets.Tick):
             # Can't infer divisions on relative or anchored offsets, as
             # divisions may now split identical index value.
             # (e.g. index_partitions = [[1, 2, 3], [3, 4, 5]])


Test patch:
diff --git a/dask/dataframe/io/tests/test_csv.py b/dask/dataframe/io/tests/test_csv.py
index 1df7202f2..f50f01f00 100644
--- a/dask/dataframe/io/tests/test_csv.py
+++ b/dask/dataframe/io/tests/test_csv.py
@@ -21,7 +21,7 @@ from dask.base import compute_as_if_collection
 from dask.bytes.core import read_bytes
 from dask.bytes.utils import compress
 from dask.core import flatten
-from dask.dataframe._compat import PANDAS_GE_140, PANDAS_GE_200, tm
+from dask.dataframe._compat import PANDAS_GE_140, PANDAS_GE_200, PANDAS_GE_220, tm
 from dask.dataframe.io.csv import (
     _infer_block_size,
     auto_blocksize,
@@ -1216,12 +1216,14 @@ def test_parse_dates_multi_column():
     """
     )
 
-    with filetext(pdmc_text) as fn:
-        ddf = dd.read_csv(fn, parse_dates=[["date", "time"]])
-        df = pd.read_csv(fn, parse_dates=[["date", "time"]])
+    warn = FutureWarning if PANDAS_GE_220 else None
+    with pytest.warns(warn, match="nested"):
+        with filetext(pdmc_text) as fn:
+            ddf = dd.read_csv(fn, parse_dates=[["date", "time"]])
+            df = pd.read_csv(fn, parse_dates=[["date", "time"]])
 
-        assert (df.columns == ddf.columns).all()
-        assert len(df) == len(ddf)
+            assert (df.columns == ddf.columns).all()
+            assert len(df) == len(ddf)
 
 
 def test_read_csv_sep():
diff --git a/dask/dataframe/tests/test_dataframe.py b/dask/dataframe/tests/test_dataframe.py
index 6fc58b075..95bb84de2 100644
--- a/dask/dataframe/tests/test_dataframe.py
+++ b/dask/dataframe/tests/test_dataframe.py
@@ -2483,89 +2483,41 @@ def test_repartition_noop(type_ctor):
 
 
 @pytest.mark.parametrize(
-    "freq, expected_freq, warning_msg",
+    "freq, expected_freq",
     [
-        (
-            "M",
-            "MS",
-            (FutureWarning, "'M' will be deprecated, please use 'ME' instead")
-            if PANDAS_GE_220
-            else None,
-        ),
-        ("ME" if PANDAS_GE_220 else "M", "MS", None),
-        ("MS", "MS", None),
-        (
-            "2M",
-            "2MS",
-            (FutureWarning, "'M' will be deprecated, please use 'ME' instead")
-            if PANDAS_GE_220
-            else None,
-        ),
-        ("Q", "QS", None),
-        ("Q-FEB", "QS-FEB", None),
-        ("2Q", "2QS", None),
-        ("2Q-FEB", "2QS-FEB", None),
-        ("2QS-FEB", "2QS-FEB", None),
-        ("BQ", "BQS", None),
-        ("2BQ", "2BQS", None),
-        ("SM", "SMS", None),
-        (
-            "A",
-            "YS" if PANDAS_GE_220 else "AS",
-            (
-                FutureWarning,
-                "'A' is deprecated and will be removed in a future version. Please use 'Y' instead of 'A'",
-            )
-            if PANDAS_GE_220
-            else None,
-        ),
-        ("Y", "YS" if PANDAS_GE_220 else "AS", None),
-        (
-            "A-JUN",
-            "YS-JUN" if PANDAS_GE_220 else "AS-JUN",
-            (
-                FutureWarning,
-                "'A-JUN' is deprecated and will be removed in a future version. Please use 'Y-JUN' instead of 'A-JUN",
-            )
-            if PANDAS_GE_220
-            else None,
-        ),
+        ("M", "MS"),
+        ("ME" if PANDAS_GE_220 else "M", "MS"),
+        ("MS", "MS"),
+        ("2M", "2MS"),
+        ("Q", "QS"),
+        ("Q-FEB", "QS-FEB"),
+        ("2Q", "2QS"),
+        ("2Q-FEB", "2QS-FEB"),
+        ("2QS-FEB", "2QS-FEB"),
+        ("BQ", "BQS"),
+        ("2BQ", "2BQS"),
+        ("SM", "SMS"),
+        ("A", "YS" if PANDAS_GE_220 else "AS"),
+        ("Y", "YS" if PANDAS_GE_220 else "AS"),
+        ("A-JUN", "YS-JUN" if PANDAS_GE_220 else "AS-JUN"),
         (
             "Y-JUN" if PANDAS_GE_220 else "A-JUN",
             "YS-JUN" if PANDAS_GE_220 else "AS-JUN",
-            None,
         ),
-        (
-            "BA",
-            "BYS" if PANDAS_GE_220 else "BAS",
-            (
-                FutureWarning,
-                "'BA' is deprecated and will be removed in a future version. Please use 'BY' instead of 'BA'",
-            )
-            if PANDAS_GE_220
-            else None,
-        ),
-        (
-            "2BA",
-            "2BYS" if PANDAS_GE_220 else "2BAS",
-            (
-                FutureWarning,
-                "'BA' is deprecated and will be removed in a future version. Please use 'BY' instead of 'BA'",
-            )
-            if PANDAS_GE_220
-            else None,
-        ),
-        ("BY", "BYS" if PANDAS_GE_220 else "BAS", None),
-        ("Y", "YS" if PANDAS_GE_220 else "AS", None),
-        (pd.Timedelta(seconds=1), pd.Timedelta(seconds=1), None),
+        ("BA", "BYS" if PANDAS_GE_220 else "BAS"),
+        ("2BA", "2BYS" if PANDAS_GE_220 else "2BAS"),
+        ("BY", "BYS" if PANDAS_GE_220 else "BAS"),
+        ("Y", "YS" if PANDAS_GE_220 else "AS"),
+        (pd.Timedelta(seconds=1), pd.Timedelta(seconds=1)),
     ],
 )
-def test_map_freq_to_period_start(freq, expected_freq, warning_msg):
-    with (
-        contextlib.nullcontext()
-        if warning_msg is None
-        else pytest.warns(warning_msg[0], match=warning_msg[1])
-    ):
+def test_map_freq_to_period_start(freq, expected_freq):
+    if PANDAS_GE_220 and freq not in ("ME", "MS", pd.Timedelta(seconds=1), "2QS-FEB"):
+        with pytest.warns(
+            FutureWarning, match="is deprecated and will be removed in a future version"
+        ):
+            new_freq = _map_freq_to_period_start(freq)
+    else:
         new_freq = _map_freq_to_period_start(freq)
     assert new_freq == expected_freq
 
diff --git a/dask/dataframe/tseries/tests/test_resample.py b/dask/dataframe/tseries/tests/test_resample.py
index c35e877b1..279740e06 100644
--- a/dask/dataframe/tseries/tests/test_resample.py
+++ b/dask/dataframe/tseries/tests/test_resample.py
@@ -124,12 +124,13 @@ def test_resample_pads_last_division_to_avoid_off_by_one():
         1559127673402811000,
     ]
 
+    freq = "1QE" if PANDAS_GE_220 else "1Q"
     df = pd.DataFrame({"Time": times, "Counts": range(len(times))})
     df["Time"] = pd.to_datetime(df["Time"], utc=True)
-    expected = df.set_index("Time").resample("1Q").size()
+    expected = df.set_index("Time").resample(freq).size()
 
     ddf = dd.from_pandas(df, npartitions=2).set_index("Time")
-    actual = ddf.resample("1Q").size().compute()
+    actual = ddf.resample(freq).size().compute()
     assert_eq(actual, expected)