Skip to content

Commit 1e6ac76

Browse files
Series.isconstant() method added
1 parent 58461fe commit 1e6ac76

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Other enhancements
4343
- :meth:`DataFrame.cummin`, :meth:`DataFrame.cummax`, :meth:`DataFrame.cumprod` and :meth:`DataFrame.cumsum` methods now have a ``numeric_only`` parameter (:issue:`53072`)
4444
- :meth:`DataFrame.fillna` and :meth:`Series.fillna` can now accept ``value=None``; for non-object dtype the corresponding NA value will be used (:issue:`57723`)
4545
- :meth:`Series.cummin` and :meth:`Series.cummax` now supports :class:`CategoricalDtype` (:issue:`52335`)
46+
- :meth:`Series.isconstant` checks if a :class:`Series` has constant values, with an optional parameter to drop NaN values (:issue:`58806`)
4647
- :meth:`Series.plot` now correctly handle the ``ylabel`` parameter for pie charts, allowing for explicit control over the y-axis label (:issue:`58239`)
4748
- Support reading Stata 110-format (Stata 7) dta files (:issue:`47176`)
4849
-
@@ -200,6 +201,7 @@ starting with 3.0, so it can be safely removed from your code.
200201
Other Deprecations
201202
^^^^^^^^^^^^^^^^^^
202203

204+
- Deprecated :meth:`series.values`, now don't drops the ``tz`` from ``dt64tz``, converts ``interval`` to ``object``, converts ``period`` to ``object``.
203205
- Deprecated :meth:`Timestamp.utcfromtimestamp`, use ``Timestamp.fromtimestamp(ts, "UTC")`` instead (:issue:`56680`)
204206
- Deprecated :meth:`Timestamp.utcnow`, use ``Timestamp.now("UTC")`` instead (:issue:`56680`)
205207
- Deprecated allowing non-keyword arguments in :meth:`DataFrame.all`, :meth:`DataFrame.min`, :meth:`DataFrame.max`, :meth:`DataFrame.sum`, :meth:`DataFrame.prod`, :meth:`DataFrame.mean`, :meth:`DataFrame.median`, :meth:`DataFrame.sem`, :meth:`DataFrame.var`, :meth:`DataFrame.std`, :meth:`DataFrame.skew`, :meth:`DataFrame.kurt`, :meth:`Series.all`, :meth:`Series.min`, :meth:`Series.max`, :meth:`Series.sum`, :meth:`Series.prod`, :meth:`Series.mean`, :meth:`Series.median`, :meth:`Series.sem`, :meth:`Series.var`, :meth:`Series.std`, :meth:`Series.skew`, and :meth:`Series.kurt`. (:issue:`57087`)

pandas/core/series.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import warnings
2626

2727
import numpy as np
28+
import numba
2829

2930
from pandas._libs import (
3031
lib,
@@ -5423,6 +5424,46 @@ def isnull(self) -> Series:
54235424
"""
54245425
return super().isnull()
54255426

5427+
def isconstant(self, dropna = False):
5428+
"""
5429+
Return if the series has constant values.
5430+
5431+
Parameters
5432+
----------
5433+
dropna : bool, default False
5434+
If True, NaN values will be ignored. If False, NaN values will be considered
5435+
in the determination of whether the series has constant values.
5436+
5437+
Returns
5438+
-------
5439+
bool
5440+
True if the series has constant values, False otherwise.
5441+
5442+
Examples
5443+
--------
5444+
>>> s = pd.Series([2, 2, 2, 2])
5445+
>>> s.isconstant()
5446+
True
5447+
5448+
>>> s = pd.Series([2, 2, 3])
5449+
>>> s.isconstant()
5450+
False
5451+
5452+
>>> s = pd.Series([2, 2, 2, np.nan])
5453+
>>> s.isconstant(dropna=True)
5454+
True
5455+
5456+
>>> s = pd.Series([2, 2, 2, np.nan])
5457+
>>> s.isconstant(dropna=False)
5458+
False
5459+
"""
5460+
v = self.to_numpy()
5461+
if dropna:
5462+
v = remove_na_arraylike(v)
5463+
if v.shape[0] == 0 or not notna(v).any():
5464+
return True
5465+
return (v[0] == v).all()
5466+
54265467
# error: Cannot determine type of 'notna'
54275468
@doc(NDFrame.notna, klass=_shared_doc_kwargs["klass"]) # type: ignore[has-type]
54285469
def notna(self) -> Series:
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import numpy as np
2+
import pytest
3+
4+
from pandas import (
5+
Series,
6+
)
7+
8+
class TestSeriesIsConstant:
9+
def test_isconstant(self):
10+
s = Series([2, 2, 2, 2])
11+
result = s.isconstant()
12+
assert result
13+
14+
s = Series([2, 2, 2, 3])
15+
result = s.isconstant()
16+
assert not result
17+
18+
s = Series([])
19+
result = s.isconstant()
20+
assert result
21+
22+
s = Series([5])
23+
result = s.isconstant()
24+
assert result
25+
26+
def test_isconstant_with_nan(self):
27+
s = Series([np.nan])
28+
result = s.isconstant()
29+
assert result
30+
31+
s = Series([np.nan,np.nan])
32+
result = s.isconstant()
33+
assert result
34+
35+
s = Series([np.nan,1])
36+
result = s.isconstant()
37+
assert not result
38+
39+
s = Series([np.nan, np.nan, 1])
40+
result = s.isconstant()
41+
assert not result
42+
43+
def test_isconstant_with_nan_dropna(self):
44+
s = Series([np.nan])
45+
result = s.isconstant(True)
46+
assert result
47+
48+
s = Series([np.nan,np.nan])
49+
result = s.isconstant(True)
50+
assert result
51+
52+
s = Series([np.nan,1])
53+
result = s.isconstant(True)
54+
assert result
55+
56+
s = Series([np.nan, np.nan, 1])
57+
result = s.isconstant(True)
58+
assert result
59+
60+
def test_isconstant_mixed_types(self):
61+
s = Series([2, '2', 2])
62+
result = s.isconstant()
63+
assert not result
64+
65+
s = Series([2, 2.0, 2])
66+
result = s.isconstant()
67+
assert result

0 commit comments

Comments
 (0)