Skip to content

Commit ffb6200

Browse files
ghasemnaddafNo-Stream
authored andcommitted
DOC: add docstring for MultiIndex.fillna (pandas-dev#18018) (pandas-dev#18269)
ENH: gb.is_monotonic_increasing pandas-dev#17015 fix rebase conflicts parametrized tests for gb.is_monotonic_increasing/decreasing ENH: gb.is_monotonic_increasing, is_monotonic_decreasing pandas-dev#17015 added tests for gb.is_monotonically_increasing()/decreasing parametrized tests for gb.is_monotonic_increasing/decreasing ENH: gb.is_monotonic_increasing pandas-dev#17015 fix rebase conflicts ENH: gb.is_monotonic_increasing pandas-dev#17015 fix rebase conflicts rebase and cleanup simplified test format fixed whatsnew to include method tags
1 parent 7f4c960 commit ffb6200

File tree

7 files changed

+119
-15
lines changed

7 files changed

+119
-15
lines changed

doc/source/api.rst

+2
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,8 @@ The following methods are available only for ``SeriesGroupBy`` objects.
20962096
SeriesGroupBy.nunique
20972097
SeriesGroupBy.unique
20982098
SeriesGroupBy.value_counts
2099+
SeriesGroupBy.is_monotonic_increasing
2100+
SeriesGroupBy.is_monotonic_decreasing
20992101

21002102
The following methods are available only for ``DataFrameGroupBy`` objects.
21012103

doc/source/whatsnew/v0.21.0.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1172,4 +1172,3 @@ Other
11721172
^^^^^
11731173
- Bug where some inplace operators were not being wrapped and produced a copy when invoked (:issue:`12962`)
11741174
- Bug in :func:`eval` where the ``inplace`` parameter was being incorrectly handled (:issue:`16732`)
1175-

doc/source/whatsnew/v0.21.1.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Other Enhancements
2222
^^^^^^^^^^^^^^^^^^
2323

2424
- :meth:`Timestamp.timestamp` is now available in Python 2.7. (:issue:`17329`)
25-
-
25+
- :meth: groupby.is_monotonic_increasing and :meth: .is_monotonic_decreasing extend :meth: Series.is_monotonic_increasing to groups, returning whether each group is monotonically increasing or decreasing, respectively. (:issue:`17015`)
2626
-
2727

2828
.. _whatsnew_0211.deprecations:

pandas/core/groupby.py

+49
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,55 @@ def pipe(self, func, *args, **kwargs):
17421742
"""
17431743
return _pipe(self, func, *args, **kwargs)
17441744

1745+
@Substitution(name='groupby')
1746+
@Appender(_doc_template)
1747+
def is_monotonic_increasing(self):
1748+
"""
1749+
Returns whether each group is monotonically increasing.
1750+
1751+
Equivalent to ``.apply(lambda x: x.is_monotonic_increasing)``.
1752+
1753+
Examples
1754+
--------
1755+
>>> source_dict = {
1756+
... 'A': ['this', 'col', 'is', 'entirely', 'irrelevant', '.'],
1757+
... 'B': ['cat_a', 'cat_a', 'cat_a', 'cat_b', 'cat_b', 'cat_b'],
1758+
... 'C': [1, 2, 3, 2, 2, 0]}
1759+
1760+
>>> df = pd.DataFrame(source_dict)
1761+
... df.groupby(['B']).C.is_monotonic_increasing()
1762+
B
1763+
cat_a True
1764+
cat_b False
1765+
Name: C, dtype: bool
1766+
1767+
"""
1768+
return self.apply(lambda x: x.is_monotonic_increasing)
1769+
1770+
@Substitution(name='groupby')
1771+
@Appender(_doc_template)
1772+
def is_monotonic_decreasing(self):
1773+
"""
1774+
Returns whether each group is monotonically decreasing.
1775+
1776+
Equivalent to ``.apply(lambda x: x.is_monotonic_decreasing)``.
1777+
1778+
Examples
1779+
--------
1780+
>>> source_dict = {
1781+
... 'A': ['this', 'col', 'is', 'entirely', 'irrelevant', '.'],
1782+
... 'B': ['cat_a', 'cat_a', 'cat_a', 'cat_b', 'cat_b', 'cat_b'],
1783+
... 'C': [1, 2, 3, 2, 2, 0]}
1784+
1785+
>>> df = pd.DataFrame(source_dict)
1786+
... df.groupby(['B']).C.is_monotonic_decreasing()
1787+
B
1788+
cat_a False
1789+
cat_b True
1790+
Name: C, dtype: bool
1791+
"""
1792+
return self.apply(lambda x: x.is_monotonic_decreasing)
1793+
17451794

17461795
GroupBy._add_numeric_operations()
17471796

pandas/core/indexes/multi.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -820,9 +820,10 @@ def duplicated(self, keep='first'):
820820

821821
return duplicated_int64(ids, keep)
822822

823-
@Appender(ibase._index_shared_docs['fillna'])
824823
def fillna(self, value=None, downcast=None):
825-
# isna is not implemented for MultiIndex
824+
"""
825+
fillna is not implemented for MultiIndex
826+
"""
826827
raise NotImplementedError('isna is not defined for MultiIndex')
827828

828829
@Appender(_index_shared_docs['dropna'])

pandas/tests/groupby/test_groupby.py

+52
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,58 @@ def test_cummin_cummax(self):
25912591
expected = pd.Series([1, 2, 1], name='b')
25922592
tm.assert_series_equal(result, expected)
25932593

2594+
@pytest.mark.parametrize('in_vals, out_vals', [
2595+
# Basics: strictly increasing (T), strictly decreasing (F),
2596+
# abs val increasing (F), non-strictly increasing (T)
2597+
([1, 2, 5, 3, 2, 0, 4, 5, -6, 1, 1],
2598+
[True, False, False, True]),
2599+
# Test with inf vals
2600+
([1, 2.1, np.inf, 3, 2, np.inf, -np.inf, 5, 11, 1, -np.inf],
2601+
[True, False, True, False]),
2602+
# Test with nan vals; should always be False
2603+
([1, 2, np.nan, 3, 2, np.nan, np.nan, 5, -np.inf, 1, np.nan],
2604+
[False, False, False, False]),
2605+
])
2606+
def test_is_monotonic_increasing(self, in_vals, out_vals):
2607+
# GH 17015
2608+
source_dict = {
2609+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
2610+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
2611+
'C': in_vals}
2612+
df = pd.DataFrame(source_dict)
2613+
result = df.groupby(['B']).C.is_monotonic_increasing()
2614+
expected = pd.Series(index=list('abcd'), name='B')
2615+
tm.assert_series_equal(result, expected)
2616+
2617+
# Also check result equal to manually taking x.is_monotonic_increasing.
2618+
expected = (
2619+
df.groupby(['B']).C.apply(lambda x: x.is_monotonic_increasing))
2620+
tm.assert_series_equal(result, expected)
2621+
2622+
@pytest.mark.parametrize('in_vals, out_vals', [
2623+
# Basics: strictly decreasing (T), strictly increasing (F),
2624+
# abs val decreasing (F), non-strictly increasing (T)
2625+
([10, 9, 7, 3, 4, 5, -3, 2, 0, 1, 1],
2626+
[True, False, False, True]),
2627+
# Test with inf vals
2628+
([np.inf, 1, -np.inf, np.inf, 2, -3, -np.inf, 5, -3, -np.inf, -np.inf],
2629+
[True, True, False, True]),
2630+
# Test with nan vals; should always be False
2631+
([1, 2, np.nan, 3, 2, np.nan, np.nan, 5, -np.inf, 1, np.nan],
2632+
[False, False, False, False]),
2633+
])
2634+
def test_is_monotonic_decreasing(self, in_vals, out_vals):
2635+
# GH 17015
2636+
source_dict = {
2637+
'A': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
2638+
'B': ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd'],
2639+
'C': in_vals}
2640+
2641+
df = pd.DataFrame(source_dict)
2642+
result = df.groupby('B').C.is_monotonic_decreasing()
2643+
expected = pd.Series(index=list('abcd'), name='B')
2644+
tm.assert_series_equal(result, expected)
2645+
25942646
def test_apply_numeric_coercion_when_datetime(self):
25952647
# In the past, group-by/apply operations have been over-eager
25962648
# in converting dtypes to numeric, in the presence of datetime

pandas/tests/groupby/test_whitelist.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,18 @@ def test_groupby_blacklist(df_letters):
239239
def test_tab_completion(mframe):
240240
grp = mframe.groupby(level='second')
241241
results = set([v for v in dir(grp) if not v.startswith('_')])
242-
expected = {
243-
'A', 'B', 'C', 'agg', 'aggregate', 'apply', 'boxplot', 'filter',
244-
'first', 'get_group', 'groups', 'hist', 'indices', 'last', 'max',
245-
'mean', 'median', 'min', 'ngroups', 'nth', 'ohlc', 'plot',
246-
'prod', 'size', 'std', 'sum', 'transform', 'var', 'sem', 'count',
247-
'nunique', 'head', 'describe', 'cummax', 'quantile',
248-
'rank', 'cumprod', 'tail', 'resample', 'cummin', 'fillna',
249-
'cumsum', 'cumcount', 'ngroup', 'all', 'shift', 'skew',
250-
'take', 'tshift', 'pct_change', 'any', 'mad', 'corr', 'corrwith',
251-
'cov', 'dtypes', 'ndim', 'diff', 'idxmax', 'idxmin',
252-
'ffill', 'bfill', 'pad', 'backfill', 'rolling', 'expanding', 'pipe'}
242+
expected = set(
243+
['A', 'B', 'C', 'agg', 'aggregate', 'apply', 'boxplot', 'filter',
244+
'first', 'get_group', 'groups', 'hist', 'indices', 'last', 'max',
245+
'mean', 'median', 'min', 'ngroups', 'nth', 'ohlc', 'plot',
246+
'prod', 'size', 'std', 'sum', 'transform', 'var', 'sem', 'count',
247+
'nunique', 'head', 'describe', 'cummax', 'quantile',
248+
'rank', 'cumprod', 'tail', 'resample', 'cummin', 'fillna',
249+
'cumsum', 'cumcount', 'ngroup', 'all', 'shift', 'skew',
250+
'take', 'tshift', 'pct_change', 'any', 'mad', 'corr', 'corrwith',
251+
'cov', 'dtypes', 'ndim', 'diff', 'idxmax', 'idxmin',
252+
'ffill', 'bfill', 'pad', 'backfill', 'rolling', 'expanding', 'pipe',
253+
'is_monotonic_increasing', 'is_monotonic_decreasing'])
253254
assert results == expected
254255

255256

0 commit comments

Comments
 (0)