Skip to content

Commit d771287

Browse files
committed
DEPR: special-casing dt64/td64 in Series.unique
1 parent b8d750f commit d771287

File tree

5 files changed

+42
-11
lines changed

5 files changed

+42
-11
lines changed

pandas/core/base.py

+10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
cast,
1616
final,
1717
)
18+
import warnings
1819

1920
import numpy as np
2021

@@ -34,6 +35,7 @@
3435
cache_readonly,
3536
doc,
3637
)
38+
from pandas.util._exceptions import find_stack_level
3739

3840
from pandas.core.dtypes.common import (
3941
is_categorical_dtype,
@@ -977,6 +979,14 @@ def unique(self):
977979
if self.dtype.kind in ["m", "M"] and isinstance(self, ABCSeries):
978980
# GH#31182 Series._values returns EA, unpack for backward-compat
979981
if getattr(self.dtype, "tz", None) is None:
982+
983+
warnings.warn(
984+
f"Series.unique behavior with {self.dtype} dtype is "
985+
"deprecated. In a future version this will return a "
986+
f"{type(self._values)} instead of a np.ndarray",
987+
FutureWarning,
988+
stacklevel=find_stack_level(),
989+
)
980990
result = np.asarray(result)
981991
else:
982992
result = unique1d(values)

pandas/tests/base/test_value_counts.py

+16-7
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ def test_value_counts_bins(index_or_series):
193193

194194
def test_value_counts_datetime64(index_or_series):
195195
klass = index_or_series
196+
warn = None if klass is Index else FutureWarning
196197

197198
# GH 3002, datetime64[ns]
198199
# don't test names though
@@ -223,12 +224,15 @@ def test_value_counts_datetime64(index_or_series):
223224
["2010-01-01 00:00:00", "2009-01-01 00:00:00", "2008-09-09 00:00:00"],
224225
dtype="datetime64[ns]",
225226
)
227+
with tm.assert_produces_warning(warn, match="DatetimeArray"):
228+
unq = s.unique()
226229
if isinstance(s, Index):
227-
tm.assert_index_equal(s.unique(), DatetimeIndex(expected))
230+
tm.assert_index_equal(unq, DatetimeIndex(expected))
228231
else:
229-
tm.assert_numpy_array_equal(s.unique(), expected)
232+
tm.assert_numpy_array_equal(unq, expected)
230233

231-
assert s.nunique() == 3
234+
with tm.assert_produces_warning(warn, match="DatetimeArray"):
235+
assert s.nunique() == 3
232236

233237
# with NaT
234238
s = df["dt"].copy()
@@ -243,7 +247,9 @@ def test_value_counts_datetime64(index_or_series):
243247
tm.assert_series_equal(result, expected_s)
244248

245249
assert s.dtype == "datetime64[ns]"
246-
unique = s.unique()
250+
warn = None if isinstance(s, DatetimeIndex) else FutureWarning
251+
with tm.assert_produces_warning(warn, match="DatetimeArray"):
252+
unique = s.unique()
247253
assert unique.dtype == "datetime64[ns]"
248254

249255
# numpy_array_equal cannot compare pd.NaT
@@ -254,8 +260,9 @@ def test_value_counts_datetime64(index_or_series):
254260
tm.assert_numpy_array_equal(unique[:3], expected)
255261
assert pd.isna(unique[3])
256262

257-
assert s.nunique() == 3
258-
assert s.nunique(dropna=False) == 4
263+
with tm.assert_produces_warning(warn, match="DatetimeArray"):
264+
assert s.nunique() == 3
265+
assert s.nunique(dropna=False) == 4
259266

260267
# timedelta64[ns]
261268
td = df.dt - df.dt + timedelta(1)
@@ -269,7 +276,9 @@ def test_value_counts_datetime64(index_or_series):
269276
if isinstance(td, Index):
270277
tm.assert_index_equal(td.unique(), expected)
271278
else:
272-
tm.assert_numpy_array_equal(td.unique(), expected.values)
279+
with tm.assert_produces_warning(FutureWarning, match="TimedeltaArray"):
280+
res = td.unique()
281+
tm.assert_numpy_array_equal(res, expected.values)
273282

274283
td2 = timedelta(1) + (df.dt - df.dt)
275284
td2 = klass(td2, name="dt")

pandas/tests/frame/test_reductions.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ def assert_stat_op_calc(
7070
f = getattr(frame, opname)
7171

7272
if check_dates:
73-
expected_warning = FutureWarning if opname in ["mean", "median"] else None
73+
expected_warning = (
74+
FutureWarning if opname in ["mean", "median", "nunique"] else None
75+
)
7476
df = DataFrame({"b": date_range("1/1/2001", periods=2)})
7577
with tm.assert_produces_warning(expected_warning):
7678
result = getattr(df, opname)()

pandas/tests/reshape/merge/test_merge.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -625,15 +625,19 @@ def test_merge_nosort(self):
625625
],
626626
}
627627
df = DataFrame.from_dict(d)
628-
var3 = df.var3.unique()
628+
with tm.assert_produces_warning(FutureWarning, match="DatetimeArray"):
629+
var3 = df.var3.unique()
629630
var3.sort()
630631
new = DataFrame.from_dict({"var3": var3, "var8": np.random.random(7)})
631632

632633
result = df.merge(new, on="var3", sort=False)
633634
exp = merge(df, new, on="var3", sort=False)
634635
tm.assert_frame_equal(result, exp)
635636

636-
assert (df.var3.unique() == result.var3.unique()).all()
637+
with tm.assert_produces_warning(FutureWarning, match="DatetimeArray"):
638+
res = df.var3.unique()
639+
expected = result.var3.unique()
640+
assert (res == expected).all()
637641

638642
@pytest.mark.parametrize(
639643
("sort", "values"), [(False, [1, 1, 0, 1, 1]), (True, [0, 1, 1, 1, 1])]

pandas/tests/test_algos.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,13 @@ def test_dtype_preservation(self, any_numpy_dtype):
534534
data = [1, 2, 2]
535535
uniques = [1, 2]
536536

537-
result = Series(data, dtype=any_numpy_dtype).unique()
537+
warn = None
538+
if np.dtype(any_numpy_dtype).kind in ["m", "M"]:
539+
warn = FutureWarning
540+
541+
ser = Series(data, dtype=any_numpy_dtype)
542+
with tm.assert_produces_warning(warn, match="DatetimeArray|TimedeltaArray"):
543+
result = ser.unique()
538544
expected = np.array(uniques, dtype=any_numpy_dtype)
539545

540546
tm.assert_numpy_array_equal(result, expected)

0 commit comments

Comments
 (0)