Skip to content

ENH: Add Styler.where #17474

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

Merged
merged 5 commits into from
Sep 11, 2017
Merged

ENH: Add Styler.where #17474

merged 5 commits into from
Sep 11, 2017

Conversation

Licht-T
Copy link
Contributor

@Licht-T Licht-T commented Sep 8, 2017

  • closes API: Add Styler.where #16255
  • tests added / passed
    Added test_where_subset in pandas/tests/io/formats/test_style.py.
  • passes git diff upstream/master -u -- "*.py" | flake8 --diff
  • whatsnew entry
    It makes the redundant style condition simple.
df.style.applymap(lambda val: 'color: %s' % 'red' if val < 0 else 'black')
df.style.where(lambda val: val < 0, 'color: red', 'color: black')

@pep8speaks
Copy link

pep8speaks commented Sep 8, 2017

Hello @Licht-T! Thanks for updating the PR.

Cheers ! There are no PEP8 issues in this Pull Request. 🍻

Comment last updated on September 10, 2017 at 14:48 Hours UTC

@codecov
Copy link

codecov bot commented Sep 8, 2017

Codecov Report

Merging #17474 into master will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #17474      +/-   ##
==========================================
- Coverage   91.16%   91.14%   -0.02%     
==========================================
  Files         163      163              
  Lines       49561    49561              
==========================================
- Hits        45180    45171       -9     
- Misses       4381     4390       +9
Flag Coverage Δ
#multiple 88.92% <ø> (ø) ⬆️
#single 40.23% <ø> (-0.07%) ⬇️
Impacted Files Coverage Δ
pandas/io/formats/style.py 100% <ø> (ø) ⬆️
pandas/io/gbq.py 25% <0%> (-58.34%) ⬇️
pandas/core/frame.py 97.72% <0%> (-0.1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7e4e8ac...9cf48fb. Read the comment docs.

@codecov
Copy link

codecov bot commented Sep 8, 2017

Codecov Report

Merging #17474 into master will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #17474      +/-   ##
==========================================
- Coverage   91.15%   91.13%   -0.02%     
==========================================
  Files         163      163              
  Lines       49534    49534              
==========================================
- Hits        45153    45144       -9     
- Misses       4381     4390       +9
Flag Coverage Δ
#multiple 88.92% <ø> (ø) ⬆️
#single 40.22% <ø> (-0.07%) ⬇️
Impacted Files Coverage Δ
pandas/io/formats/style.py 100% <ø> (ø) ⬆️
pandas/io/gbq.py 25% <0%> (-58.34%) ⬇️
pandas/core/frame.py 97.72% <0%> (-0.1%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e6aed2e...82ae1dc. Read the comment docs.

Copy link
Contributor

@jreback jreback left a 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 whatsnew note on Other Enahancements as well as use this in the notebook where appropriate

"""
Apply a function elementwise, updating the HTML
representation with a style which is selected in
accordance with the return value of a function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a versionadded tag

@@ -623,6 +623,32 @@ def applymap(self, func, subset=None, **kwargs):
(func, subset), kwargs))
return self

def where(self, func, style1, style2='', subset=None, **kwargs):
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaults should be None not ''


Parameters
----------
func : function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callable

----------
func : function
``func`` should take a scalar and return a boolean
style1 : a style applied when ``func`` returns true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style1: str
when applied......

@@ -265,6 +265,26 @@ def f(x):
col in self.df.loc[slice_].columns)
assert result == expected

def test_where_subset(self):
def f(x):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a comment with the issue number (this PR number)

@jreback jreback added the Output-Formatting __repr__ of pandas objects, to_string label Sep 8, 2017
for slice_ in slices:
result = self.df.style.where(f, style1, style2,
subset=slice_)._compute().ctx
expected = self.df.style.applymap(g, subset=slice_)._compute().ctx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are fine, but could you add one test that checks the generated values directly against the dictionary?

@Licht-T
Copy link
Contributor Author

Licht-T commented Sep 9, 2017

@jreback @TomAugspurger Thanks for your review. Fixed and added some new tests.

@Licht-T
Copy link
Contributor Author

Licht-T commented Sep 9, 2017

Travis CI seems not work well due to its own error.
Could someone restart the Travis CI build?

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems ok, @TomAugspurger . do we have a section in api.rst for things like this?

@@ -112,6 +112,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:`Styler.where` has been implemented. It enables simple DataFrame styling on the Jupyter notebook (:issue:`17474`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls label this as a convenience for Styler.applymap


Parameters
----------
func : callable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should mimic the signature of DataFrame.where as much as possible

func -> cond
style1 -> value
style2 -> other

@Licht-T
Copy link
Contributor Author

Licht-T commented Sep 10, 2017

@jreback Thanks for your suggestion. Fixed!

@@ -112,6 +112,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:`Styler.where` has been implemented. It is as a convenience for Styler.applymap and enables simple DataFrame styling on the Jupyter notebook (:issue:`17474`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use :func:`Styler.applymap` as well


Returns
-------
self : Styler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a See Also here (pointing to .applymap) and the reciprical one there

@@ -112,6 +112,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:`Styler.where` has been implemented. It is as a convenience for Styler.applymap and enables simple DataFrame styling on the Jupyter notebook (:issue:`17474`).


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.where needs to be added to api.rst

@Licht-T
Copy link
Contributor Author

Licht-T commented Sep 10, 2017

@jreback Thanks. All is now fixed.

@jreback jreback added this to the 0.21.0 milestone Sep 11, 2017
@jreback jreback merged commit 42ed4f1 into pandas-dev:master Sep 11, 2017
@jreback
Copy link
Contributor

jreback commented Sep 11, 2017

thanks @Licht-T

If you'd have a pass thru the actual documentation notebook and make a PR for anything where we should logically use .where to make the syntax more clear would be great (or indicate that it looks good).

alanbato pushed a commit to alanbato/pandas that referenced this pull request Nov 10, 2017
No-Stream pushed a commit to No-Stream/pandas that referenced this pull request Nov 28, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Output-Formatting __repr__ of pandas objects, to_string
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API: Add Styler.where
4 participants