Skip to content
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 14194: add style option for hiding index and columns #16141

Merged
merged 7 commits into from
Nov 19, 2017

Conversation

nchmura4
Copy link
Contributor

@nchmura4 nchmura4 commented Apr 26, 2017

@codecov
Copy link

codecov bot commented Apr 26, 2017

Codecov Report

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

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #16141      +/-   ##
==========================================
- Coverage   91.39%   91.36%   -0.04%     
==========================================
  Files         164      164              
  Lines       49854    49790      -64     
==========================================
- Hits        45566    45492      -74     
- Misses       4288     4298      +10
Flag Coverage Δ
#multiple 89.17% <ø> (-0.02%) ⬇️
#single 39.49% <ø> (-0.01%) ⬇️
Impacted Files Coverage Δ
pandas/io/formats/style.py 100% <ø> (ø) ⬆️
pandas/io/gbq.py 25% <0%> (-58.34%) ⬇️
pandas/tseries/offsets.py 96.91% <0%> (-0.16%) ⬇️
pandas/core/panel.py 97.14% <0%> (-0.15%) ⬇️
pandas/core/frame.py 97.8% <0%> (-0.1%) ⬇️
pandas/core/indexes/datetimes.py 95.48% <0%> (ø) ⬆️
pandas/core/indexes/range.py 95.66% <0%> (ø) ⬆️
pandas/core/reshape/reshape.py 100% <0%> (ø) ⬆️
pandas/core/indexes/timedeltas.py 91.14% <0%> (ø) ⬆️
pandas/core/indexes/multi.py 96.38% <0%> (ø) ⬆️
... and 10 more

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 9c799e2...cb779ec. Read the comment docs.

@@ -69,6 +69,9 @@ class Styler(object):
a unique identifier to avoid CSS collisons; generated automatically
caption: str, default None
caption to attach to the table
index_hidden: bool, default False
hides the index in the html output
Copy link
Contributor

Choose a reason for hiding this comment

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

index=True is our standard way of doing this

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 blank line before version added

Copy link
Contributor

Choose a reason for hiding this comment

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

And add an entry for hidden_columns

ctx = self.df.style._translate()
self.assertTrue(ctx['body'][0][0]['is_visible'])
self.assertTrue(ctx['head'][0][0]['is_visible'])
ctx2 = self.df.style.hide_index()._translate()
Copy link
Contributor

Choose a reason for hiding this comment

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

use bare asset here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Do you mean use ctx intead of ctx#?

Copy link
Contributor

Choose a reason for hiding this comment

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

no I mean

assert cts['body'][0][0]['is_visible']

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it, thanks!

@@ -223,7 +234,7 @@ def format_attr(pair):
row_es = [{"type": "th",
"value": BLANK_VALUE,
"display_value": BLANK_VALUE,
"is_visible": True,
"is_visible": (not index_hidden),
Copy link
Contributor

Choose a reason for hiding this comment

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

You shouldn't need the parentheses here.

@@ -69,6 +69,9 @@ class Styler(object):
a unique identifier to avoid CSS collisons; generated automatically
caption: str, default None
caption to attach to the table
index_hidden: bool, default False
hides the index in the html output
Copy link
Contributor

Choose a reason for hiding this comment

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

And add an entry for hidden_columns

@jreback jreback added the Output-Formatting __repr__ of pandas objects, to_string label Apr 27, 2017
assert(ctx['body'][0][0]['is_visible'])
assert(ctx['head'][0][0]['is_visible'])
ctx2 = self.df.style.hide_index()._translate()
self.assertFalse(ctx2['body'][0][0]['is_visible'])
Copy link
Member

Choose a reason for hiding this comment

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

Don't use self.assertFalse. Use assert not ... instead.

# single named index
ctx3 = self.df.set_index('A').style._translate()
assert(ctx3['body'][0][0]['is_visible'])
self.assertEqual(len(ctx3['head']), 2) # 2 header levels
Copy link
Member

Choose a reason for hiding this comment

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

Don't use self.assertEqual. Use assert ... == ... instead.

@gfyoung
Copy link
Member

gfyoung commented Apr 29, 2017

@nchmura4 : My two comments regarding self.assertEqual and self.assertFalse should be applied to ALL places where you wrote that. We're making a massive effort to remove function calls like this, so before this is merged, the diff should be checked to make sure that those (and any others) are not used.

@nchmura4
Copy link
Contributor Author

nchmura4 commented May 1, 2017

@gfyoung got it, thanks for explaining

Copy link
Contributor

@TomAugspurger TomAugspurger left a comment

Choose a reason for hiding this comment

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

Could you clear all the cell output in the notebook? We commit just the source to the repository, then nbsphinx executes it while building the docs.

@@ -257,8 +274,8 @@ def format_attr(pair):
row_es.append(es)
head.append(row_es)

if self.data.index.names and not all(x is None
for x in self.data.index.names):
if self.data.index.names and index_visible\
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you write this is

    if (self.data.index.names and index_visible
            and not all(x is None for x in self.data.index.names)):

we try to avoid continuation backslashes

@@ -49,9 +49,12 @@ Indexing
I/O
^^^

- :class:`pandas.io.formats.style.Styler` now has ``index`` parameter and corresponding method ``hide_index()`` to determine whether the index will be rendered in ouptut (:issue:`14194`)
Copy link
Contributor

Choose a reason for hiding this comment

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

this would be in Other Enhancements


.. versionadded:: 0.20.2

hidden_cols: IndexSlice, default None
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this not called columns? (or do we have that are already)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i thought hidden_cols was more intuitive of a name, since these columns won't show up. but i'm fine with changing it if it breaks the standard

def hide_columns(self, subset):
"""
Hide columns from rendering.

Copy link
Contributor

Choose a reason for hiding this comment

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

how does subset make sense here? does it make sense to hide some columns?

Copy link
Contributor Author

@nchmura4 nchmura4 May 12, 2017

Choose a reason for hiding this comment

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

The idea is that you may have columns that are needed for formatting -- determining the color of a row, for example -- but you may not want to display them. For example, lets say you had a dataframe with columns City and AvgTemp. Avg Temp was used by Styler to color each row. But in the final rendering, you only want to display city (colored appropriately). AFAIK there is no way to do that right now, but with this change you could do df.style.hide_columns(['AvgTemp']). You only want to hide AvgTemp.

Copy link
Contributor

Choose a reason for hiding this comment

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

this is a bit unusual for pandas, but I think it's fine here. It's kind of like drop, except it's hiding instead of dropping.

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should support df.style[list_of_selected_columns] for showing some columns. (separate discussion)

def test_hide_single_index(self):
# single unnamed index
ctx = self.df.style._translate()
assert(ctx['body'][0][0]['is_visible'])
Copy link
Member

Choose a reason for hiding this comment

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

We generally use the raw assert with no parentheses. This should be applied to ALL places where you added an assertion statement.

@@ -118,7 +127,8 @@ class Styler(object):
template = env.get_template("html.tpl")

def __init__(self, data, precision=None, table_styles=None, uuid=None,
caption=None, table_attributes=None):
caption=None, table_attributes=None, index=True,
hidden_cols=None):
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 rename hidden_cols to hidden_columns

self.index_visible = index
if hidden_cols is None:
hidden_cols = []
self.hidden_cols = hidden_cols
Copy link
Contributor

Choose a reason for hiding this comment

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

Here as well.

@jreback
Copy link
Contributor

jreback commented Aug 1, 2017

can you rebase

@nchmura4
Copy link
Contributor Author

nchmura4 commented Aug 6, 2017

thanks, done.

@jreback
Copy link
Contributor

jreback commented Sep 23, 2017

can you rebase / update

@nchmura4
Copy link
Contributor Author

@jreback - done. i updated all the version references, as well. let me know if you need me to do anything else.

@gfyoung
Copy link
Member

gfyoung commented Sep 25, 2017

https://circleci.com/gh/pandas-dev/pandas/4945#tests/containers/3

@jreback : Is this symptomatic of another numpy compatibility issue?


Parameters
----------

Copy link
Member

Choose a reason for hiding this comment

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

Remove this line.

@@ -891,6 +891,116 @@ def test_mi_sparse_column_names(self):
]
assert head == expected

def test_hide_single_index(self):
Copy link
Member

@gfyoung gfyoung Sep 25, 2017

Choose a reason for hiding this comment

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

For this test all of other tests that you've added, reference your PR (or issue number) under the function definition for that test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks!

@@ -85,5 +85,12 @@ Numeric



Other Enhancements
^^^^^^^^^^^^^^^^^^

Copy link
Contributor

Choose a reason for hiding this comment

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

move to 0.21.0

@@ -70,6 +70,15 @@ class Styler(object):
a unique identifier to avoid CSS collisons; generated automatically
caption: str, default None
caption to attach to the table
index: bool, default True
determines if the index is rendered in the html output

Copy link
Contributor

Choose a reason for hiding this comment

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

change to 0.21.0

@@ -70,6 +70,15 @@ class Styler(object):
a unique identifier to avoid CSS collisons; generated automatically
caption: str, default None
caption to attach to the table
index: bool, default True
determines if the index is rendered in the html output
Copy link
Contributor

Choose a reason for hiding this comment

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

I realize these new parametrize should directly reflect the methods, so use hide_index, hide_columns

@@ -140,6 +150,11 @@ def __init__(self, data, precision=None, table_styles=None, uuid=None,
precision = get_option('display.precision')
self.precision = precision
self.table_attributes = table_attributes
self.index_visible = index
Copy link
Contributor

Choose a reason for hiding this comment

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

just call this .hidden_index/.hidden_columns to avoid the name clash

@@ -163,6 +163,9 @@ Other Enhancements
- :func:`Categorical.rename_categories` now accepts a dict-like argument as `new_categories` and only updates the categories found in that dict. (:issue:`17336`)
- :func:`read_excel` raises ``ImportError`` with a better message if ``xlrd`` is not installed. (:issue:`17613`)
- :meth:`DataFrame.assign` will preserve the original order of ``**kwargs`` for Python 3.6+ users instead of sorting the column names
- :class:`pandas.io.formats.style.Styler` now has ``index`` parameter and corresponding method ``hide_index()`` to determine whether the index will be rendered in ouptut (:issue:`14194`)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would just highlite the methods, which are more idiomatic.

self.index_visible = index
if hidden_columns is None:
hidden_columns = []
self.hidden_columns = hidden_columns
Copy link
Contributor

Choose a reason for hiding this comment

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

I actually wouldn't add these to the Styler.__init__ prefer these as just methods. (like almost everything else). having more than 1 way to do things is not great.

@TomAugspurger
Copy link
Contributor

Merged in master to fix the Circle-CI build. Hopefully it passes this time.

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.

I think this only needs a bit of updating

@@ -164,6 +164,9 @@ Other Enhancements
- :func:`read_excel` raises ``ImportError`` with a better message if ``xlrd`` is not installed. (:issue:`17613`)
- :func:`read_json` now accepts a ``chunksize`` parameter that can be used when ``lines=True``. If ``chunksize`` is passed, read_json now returns an iterator which reads in ``chunksize`` lines with each iteration. (:issue:`17048`)
- :meth:`DataFrame.assign` will preserve the original order of ``**kwargs`` for Python 3.6+ users instead of sorting the column names
- :class:`pandas.io.formats.style.Styler` now has method ``hide_index()`` to determine whether the index will be rendered in ouptut (:issue:`14194`)
Copy link
Contributor

Choose a reason for hiding this comment

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

move to 0.22

"""
Hide any indices from rendering.

.. versionadded:: 0.21.0
Copy link
Contributor

Choose a reason for hiding this comment

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

update

"""
Hide columns from rendering.

.. versionadded:: 0.21.0
Copy link
Contributor

Choose a reason for hiding this comment

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

same

@TomAugspurger
Copy link
Contributor

Let us know when all the tests pass.

@@ -24,7 +24,8 @@ Other Enhancements

- Better support for :func:`Dataframe.style.to_excel` output with the ``xlsxwriter`` engine. (:issue:`16149`)
- :func:`pandas.tseries.frequencies.to_offset` now accepts leading '+' signs e.g. '+1h'. (:issue:`18171`)
-
- :class:`pandas.io.formats.style.Styler` now has ``index`` parameter and corresponding method ``hide_index()`` to determine whether the index will be rendered in ouptut (:issue:`14194`)
- :class:`pandas.io.formats.style.Styler` now has ``hidden_cols`` parameter and corresponding method ``hide_columns()`` to determine whether columns will be hidden in output (:issue:`14194`)
Copy link
Contributor

Choose a reason for hiding this comment

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

hide_cols -> hide_columns

Copy link
Contributor

Choose a reason for hiding this comment

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

didn't we eliminate the paramaters as user facing and only use the methods? (which i think is better anyhow)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jreback yes, thanks, i should have caught that. fixed!

@jreback jreback added this to the 0.22.0 milestone Nov 19, 2017
@jreback jreback merged commit b00e62c into pandas-dev:master Nov 19, 2017
@jreback
Copy link
Contributor

jreback commented Nov 19, 2017

thanks @nchmura4

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.

ENH: DataFrame.style option for hiding the index
4 participants