-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
ENH: gb.is_monotonic_increasing #17015 #17453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH: gb.is_monotonic_increasing #17015 #17453
Conversation
tests go in |
doc/source/whatsnew/v0.21.0.txt
Outdated
@@ -130,7 +130,7 @@ Other Enhancements | |||
- `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`). | |||
- :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). | |||
- :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`) | |||
|
|||
- :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`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this won't work for :func:
as you have it written, I think enough is to say .is_monotonic_increasing/decreasing
is added to .groupby()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this fix and the above test location, which now seems painfully obvious. Will patch up the PR and fix tomorrow.
Added basic tests, for strictly monotonically increasing/decreasing, non-strictly, groups with inf, groups with nan, and to check method result == .apply(lambda x: x.is_monotonic_increasing) (though the method is just syntactic sugar in this implementation). (Not sure how much detail should be in the tests of gb.is_monotonic_increasing vs. Series.is_monotonic_increasing.) |
pandas/tests/groupby/test_groupby.py
Outdated
df = pd.DataFrame(source_dict) | ||
result = df.groupby(['B']).C.is_monotonic_decreasing() | ||
expected = pd.Series(index=['a', 'b', 'c', 'd'], | ||
data=[False, False, False, False], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI some of these may be less verbose as pytest parameterized tests, though not a big impact
Thanks for the PR!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback. I did consider parametrizing, but when I've done it before, it inflated the test count (i.e. if I parametrized using the same test cases for both is_monotonic_increasing() and is_monotonic_decreasing, I'd have added two tests, rather than one. Maybe there's a way around that.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually we would prefer to parametrize, it reduces the amount of duplication in code. feel free.
pandas/tests/groupby/test_groupby.py
Outdated
@@ -3843,6 +3843,128 @@ def test_cummin_cummax(self): | |||
expected = pd.Series([1, 2, 1], name='b') | |||
tm.assert_series_equal(result, expected) | |||
|
|||
def test_is_increasing_is_decreasing(self): | |||
# GH 17015 | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't really need all this, as is_montonic
and friends are already well tested in Index
(where they are actually implemented), but no big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
figured as much but wasn't sure whether to test here and risk duplication or not test here and have "untested" code.
pandas/tests/groupby/test_groupby.py
Outdated
name='C') | ||
expected.index.name = 'B' | ||
tm.assert_series_equal(result, expected) | ||
# Also check result equal to manually taking x.is_monotonic_increasing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank line
pandas/tests/groupby/test_groupby.py
Outdated
name='C') | ||
expected.index.name = 'B' | ||
tm.assert_series_equal(result, expected) | ||
# Also check result equal to manually taking x.is_monotonic_increasing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
pandas/tests/groupby/test_groupby.py
Outdated
df = pd.DataFrame(source_dict) | ||
result = df.groupby(['B']).C.is_monotonic_decreasing() | ||
expected = pd.Series(index=['a', 'b', 'c', 'd'], | ||
data=[False, False, False, False], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually we would prefer to parametrize, it reduces the amount of duplication in code. feel free.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also update api.rst for these methods (and I suspect others might be missing as well for GroupBy and sub-classes)
Codecov Report
@@ Coverage Diff @@
## master #17453 +/- ##
==========================================
- Coverage 91.61% 91.58% -0.04%
==========================================
Files 150 150
Lines 48807 48867 +60
==========================================
+ Hits 44716 44755 +39
- Misses 4091 4112 +21
Continue to review full report at Codecov.
|
@jreback I went ahead and parametrized the tests. Wanted to have the method itself as a param as I could then just use one test function to test both is_monotonic_increasing and decreasing, but I couldn't figure out a way to pass a method as a param. Also added these to SeriesGroupBy in api.rst. Not sure what else I should add. If I run the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you rebase
doc/source/whatsnew/v0.21.0.txt
Outdated
@@ -130,7 +130,7 @@ Other Enhancements | |||
- `read_*` methods can now infer compression from non-string paths, such as ``pathlib.Path`` objects (:issue:`17206`). | |||
- :func:`pd.read_sas()` now recognizes much more of the most frequently used date (datetime) formats in SAS7BDAT files (:issue:`15871`). | |||
- :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`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move to 0.21.1
I rebased to try to integrate changes to pandas-dev/pandas, but it seems the commit history is profoundly screwed up now. (It does look to me like the upstream changes are now reflected, though.) Could someone suggest how to fix this? |
@AdamShamlian you need to build the extensions
you should do this whenever you pull (it has no effect if they are already built). extensions are undergoing a lot of renovation lately. |
95d4ba8
to
ea42697
Compare
@No-Stream I rebased you. please have a look thru and make any additional corrections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small changes. pls rebase. ping on green.
doc/source/whatsnew/v0.21.1.txt
Outdated
@@ -22,7 +22,7 @@ Other Enhancements | |||
^^^^^^^^^^^^^^^^^^ | |||
|
|||
- :meth:`Timestamp.timestamp` is now available in Python 2.7. (:issue:`17329`) | |||
- | |||
- :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`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can add :func:
where needed here
pandas/tests/groupby/test_groupby.py
Outdated
'C': in_vals} | ||
df = pd.DataFrame(source_dict) | ||
result = df.groupby(['B']).C.is_monotonic_increasing() | ||
expected = pd.Series(index=['a', 'b', 'c', 'd'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can write this as Index(list('abcd'), name='B')
…ev#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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor comments, otherwise lgtm.
doc/source/whatsnew/v0.21.0.txt
Outdated
@@ -1172,4 +1172,3 @@ Other | |||
^^^^^ | |||
- Bug where some inplace operators were not being wrapped and produced a copy when invoked (:issue:`12962`) | |||
- Bug in :func:`eval` where the ``inplace`` parameter was being incorrectly handled (:issue:`16732`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you can revert this file
doc/source/whatsnew/v0.21.1.txt
Outdated
@@ -23,6 +23,7 @@ Other Enhancements | |||
|
|||
- :meth:`Timestamp.timestamp` is now available in Python 2.7. (:issue:`17329`) | |||
- :class:`Grouper` and :class:`TimeGrouper` now have a friendly repr output (:issue:`18203`). | |||
- :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`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's move to 0.22
pandas/tests/groupby/test_groupby.py
Outdated
# abs val increasing (F), non-strictly increasing (T) | ||
([1, 2, 5, 3, 2, 0, 4, 5, -6, 1, 1], | ||
[True, False, False, True]), | ||
# Test with inf vals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a blank line before comments
pandas/tests/groupby/test_groupby.py
Outdated
'C': in_vals} | ||
df = pd.DataFrame(source_dict) | ||
result = df.groupby('B').C.is_monotonic_increasing() | ||
expected = pd.Series(index=list('abcd'), data=out_vals, name='C') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can construct the index=Index(list('abcd'), name='B')
can you rebase and update according to comments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. small doc-change.
doc/source/whatsnew/v0.22.0.txt
Outdated
@@ -138,6 +138,8 @@ Other Enhancements | |||
- :func:`Series` / :func:`DataFrame` tab completion also returns identifiers in the first level of a :func:`MultiIndex`. (:issue:`16326`) | |||
- :func:`read_excel()` has gained the ``nrows`` parameter (:issue:`16645`) | |||
- :func:``DataFrame.to_json`` and ``Series.to_json`` now accept an ``index`` argument which allows the user to exclude the index from the JSON output (:issue:`17394`) | |||
- :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`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these need to be
:func:`SeriesGroupBy.is_monotonic_increasing`
(and so on)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check if it is possible to completely remove the is_monotonic_increasing
function definitions by adding them to _series_apply_whitelist
@jorisvandenbossche was able to implement it as you requested. This change does make the syntax a bit uglier. i.e. it's |
@gfyoung can you rebase this |
@jreback : Resolved the merge conflict, though I don't know if the CI will be all green. |
That's actually a good point. We don't have many precedents for attributes on groupby objects (or for methods that are the equivalent of attributes). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am ok with this being an attribute
it is consistent with Series/Index
doc/source/whatsnew/v0.23.0.txt
Outdated
@@ -323,6 +323,7 @@ Other Enhancements | |||
|
|||
- ``IntervalIndex.astype`` now supports conversions between subtypes when passed an ``IntervalDtype`` (:issue:`19197`) | |||
- :class:`IntervalIndex` and its associated constructor methods (``from_arrays``, ``from_breaks``, ``from_tuples``) have gained a ``dtype`` parameter (:issue:`19262`) | |||
- :func: groupby.is_monotonic_increasing and :func: .is_monotonic_decreasing extend :func: Series.is_monotonic_increasing to groups, returning whether each group is monotonically increasing or decreasing, respectively. (:issue:`17015`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these will not render correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
doc/source/whatsnew/v0.23.0.txt
Outdated
@@ -323,6 +323,7 @@ Other Enhancements | |||
|
|||
- ``IntervalIndex.astype`` now supports conversions between subtypes when passed an ``IntervalDtype`` (:issue:`19197`) | |||
- :class:`IntervalIndex` and its associated constructor methods (``from_arrays``, ``from_breaks``, ``from_tuples``) have gained a ``dtype`` parameter (:issue:`19262`) | |||
- :func:`groupby.is_monotonic_increasing` and :func:`.is_monotonic_decreasing` extend `:func: Series.is_monotonic_increasing` to groups, returning whether each group is monotonically increasing or decreasing, respectively. (:issue:`17015`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
:func:`SeriesGroupBy.is_monotonic_increasing`
I also don't think "extend" is the right word. Perhaps just
Added :func:`SeriesGroupBy.is_monotonic_increasing` and :func:`SeriesGroupBy.is_monotonic_decreasing` (:issue:`17015`)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. Fixed.
look ok to me. @gfyoung can you rebase again. |
@jreback @jorisvandenbossche : CI is passing, and the PR is mergeable. PTAL. |
Thanks @No-Stream and @gfyoung |
updated test_tab_completion to expect additional functions
is_monotonic_increasing
andis_monotonic_decreasing
added (semi-redundant) tests of gb.is_monotonically_increasing() - strictly increasing/decreasing, non-strictly, w/ inf vals, w/ nan vals
git diff upstream/master -u -- "*.py" | flake8 --diff
added at the end of the
Other Enhancements
sectionThis is my first PR to Pandas, so I don't doubt that I'll need to edit things.