Skip to content

Commit c156b12

Browse files
authored
BUG: nunique not ignoring both None and np.nan (#37607)
1 parent 365d843 commit c156b12

File tree

3 files changed

+12
-6
lines changed

3 files changed

+12
-6
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ Other
581581
- Bug in :meth:`Index.union` behaving differently depending on whether operand is a :class:`Index` or other list-like (:issue:`36384`)
582582
- Passing an array with 2 or more dimensions to the :class:`Series` constructor now raises the more specific ``ValueError``, from a bare ``Exception`` previously (:issue:`35744`)
583583
- Bug in ``accessor.DirNamesMixin``, where ``dir(obj)`` wouldn't show attributes defined on the instance (:issue:`37173`).
584+
- Bug in :meth:`Series.nunique` with ``dropna=True`` was returning incorrect results when both ``NA`` and ``None`` missing values were present (:issue:`37566`)
584585

585586
.. ---------------------------------------------------------------------------
586587

pandas/core/base.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
is_scalar,
3434
)
3535
from pandas.core.dtypes.generic import ABCDataFrame, ABCIndexClass, ABCSeries
36-
from pandas.core.dtypes.missing import isna
36+
from pandas.core.dtypes.missing import isna, remove_na_arraylike
3737

3838
from pandas.core import algorithms
3939
from pandas.core.accessor import DirNamesMixin
@@ -1081,11 +1081,8 @@ def nunique(self, dropna: bool = True) -> int:
10811081
>>> s.nunique()
10821082
4
10831083
"""
1084-
uniqs = self.unique()
1085-
n = len(uniqs)
1086-
if dropna and isna(uniqs).any():
1087-
n -= 1
1088-
return n
1084+
obj = remove_na_arraylike(self) if dropna else self
1085+
return len(obj.unique())
10891086

10901087
@property
10911088
def is_unique(self) -> bool:

pandas/tests/base/test_unique.py

+8
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,11 @@ def test_unique_bad_unicode(idx_or_series_w_bad_unicode):
121121
else:
122122
expected = np.array(["\ud83d"], dtype=object)
123123
tm.assert_numpy_array_equal(result, expected)
124+
125+
126+
@pytest.mark.parametrize("dropna", [True, False])
127+
def test_nunique_dropna(dropna):
128+
# GH37566
129+
s = pd.Series(["yes", "yes", pd.NA, np.nan, None, pd.NaT])
130+
res = s.nunique(dropna)
131+
assert res == 1 if dropna else 5

0 commit comments

Comments
 (0)