Skip to content

Commit 740c7c2

Browse files
committed
added tests for gb.is_monotonically_increasing()/decreasing
1 parent e99897c commit 740c7c2

File tree

2 files changed

+123
-1
lines changed

2 files changed

+123
-1
lines changed

doc/source/whatsnew/v0.21.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ Other Enhancements
130130
- `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`).
131131
- :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`).
132132
- :func:`DataFrame.items` and :func:`Series.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`)
133-
- :func: groupby.is_monotonic_increasing and .is_monotonic_decreasing extend Series.is_monotonic_increasing to groups, returning whether each group is monotonically increasing or decreasing, respectively. (:issue:`17015`)
133+
- is_monotonic_increasing/decreasing is added to .groupby(). (:issue:`17015`)
134134

135135

136136
.. _whatsnew_0210.api_breaking:

pandas/tests/groupby/test_groupby.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,6 +3843,128 @@ def test_cummin_cummax(self):
38433843
expected = pd.Series([1, 2, 1], name='b')
38443844
tm.assert_series_equal(result, expected)
38453845

3846+
def test_is_increasing_is_decreasing(self):
3847+
# GH 17015
3848+
3849+
# Basics: strictly increasing (T), strictly decreasing (F),
3850+
# abs val increasing (F), non-strictly increasing (T)
3851+
source_dict = {
3852+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3853+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3854+
'C': [1, 2, 5, 3, 2, 0, 4, 5, -6, 1, 1]}
3855+
df = pd.DataFrame(source_dict)
3856+
result = df.groupby(['B']).C.is_monotonic_increasing()
3857+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3858+
data=[True, False, False, True],
3859+
name='C')
3860+
expected.index.name = 'B'
3861+
tm.assert_series_equal(result, expected)
3862+
# Also check result equal to manually taking x.is_monotonic_increasing.
3863+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_increasing)
3864+
tm.assert_series_equal(result, expected)
3865+
3866+
# Test with inf vals
3867+
source_dict = {
3868+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3869+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3870+
'C': [1, 2.1, np.inf, 3, 2, np.inf, -np.inf, 5, 11, 1, -np.inf]}
3871+
expected.index.name = 'B'
3872+
df = pd.DataFrame(source_dict)
3873+
result = df.groupby(['B']).C.is_monotonic_increasing()
3874+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3875+
data=[True, False, True, False],
3876+
name='C')
3877+
expected.index.name = 'B'
3878+
tm.assert_series_equal(result, expected)
3879+
# Also check result equal to manually taking x.is_monotonic_increasing.
3880+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_increasing)
3881+
tm.assert_series_equal(result, expected)
3882+
3883+
# Test with nan vals; should always be False
3884+
source_dict = {
3885+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3886+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3887+
'C': [1, 2, np.nan, 3, 2, np.nan, np.nan, 5, -np.inf, 1, np.nan]}
3888+
df = pd.DataFrame(source_dict)
3889+
result = df.groupby(['B']).C.is_monotonic_increasing()
3890+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3891+
data=[False, False, False, False],
3892+
name='C')
3893+
expected.index.name = 'B'
3894+
tm.assert_series_equal(result, expected)
3895+
# Also check result equal to manually taking x.is_monotonic_increasing.
3896+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_increasing)
3897+
tm.assert_series_equal(result, expected)
3898+
3899+
# Test with single member groups; should be True except for np.nan
3900+
source_dict = {
3901+
'A': ['1', '2', '3', '4'],
3902+
'B': ['a', 'b', 'c', 'd'],
3903+
'C': [1, 2, np.nan, np.inf]}
3904+
df = pd.DataFrame(source_dict)
3905+
result = df.groupby(['B']).C.is_monotonic_increasing()
3906+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3907+
data=[True, True, False, True],
3908+
name='C')
3909+
expected.index.name = 'B'
3910+
expected.index.name = 'B'
3911+
tm.assert_series_equal(result, expected)
3912+
# Also check result equal to manually taking x.is_monotonic_increasing.
3913+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_increasing)
3914+
tm.assert_series_equal(result, expected)
3915+
3916+
# As above, for .is_monotonic_decreasing()
3917+
# Basics: strictly decreasing (T), strictly increasing (F),
3918+
# abs val decreasing (F), non-strictly increasing (T)
3919+
source_dict = {
3920+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3921+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3922+
'C': [10, 9, 7, 3, 4, 5, -3, 2, 0, 1, 1]}
3923+
df = pd.DataFrame(source_dict)
3924+
result = df.groupby(['B']).C.is_monotonic_decreasing()
3925+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3926+
data=[True, False, False, True],
3927+
name='C')
3928+
expected.index.name = 'B'
3929+
tm.assert_series_equal(result, expected)
3930+
# Also check result equal to manually taking x.is_monotonic_decreasing.
3931+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_decreasing)
3932+
tm.assert_series_equal(result, expected)
3933+
3934+
# Test with inf vals
3935+
source_dict = {
3936+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3937+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3938+
'C': [np.inf, 1, -np.inf, np.inf, 2, -3, -np.inf, 5, -3, -np.inf,
3939+
-np.inf]}
3940+
df = pd.DataFrame(source_dict)
3941+
result = df.groupby(['B']).C.is_monotonic_decreasing()
3942+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3943+
data=[True, True, False, True],
3944+
name='C')
3945+
expected.index.name = 'B'
3946+
tm.assert_series_equal(result, expected)
3947+
# Also check result equal to manually taking x.is_monotonic_decreasing.
3948+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_decreasing)
3949+
tm.assert_series_equal(result, expected)
3950+
3951+
# Test with nan vals; should always be False
3952+
source_dict = {
3953+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
3954+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
3955+
'C': [1, 2, np.nan, 3, 2, np.nan, np.nan, 5, -np.inf, 1, np.nan]}
3956+
df = pd.DataFrame(source_dict)
3957+
result = df.groupby(['B']).C.is_monotonic_decreasing()
3958+
expected = pd.Series(index=['a', 'b', 'c', 'd'],
3959+
data=[False, False, False, False],
3960+
name='C')
3961+
expected.index.name = 'B'
3962+
tm.assert_series_equal(result, expected)
3963+
# Also check result equal to manually taking x.is_monotonic_decreasing.
3964+
expected = df.groupby('B').C.apply(lambda x: x.is_monotonic_decreasing)
3965+
tm.assert_series_equal(result, expected)
3966+
3967+
38463968
def test_apply_numeric_coercion_when_datetime(self):
38473969
# In the past, group-by/apply operations have been over-eager
38483970
# in converting dtypes to numeric, in the presence of datetime

0 commit comments

Comments
 (0)