-
- Notifications
You must be signed in to change notification settings - Fork 19.4k
Series repr html only #29383
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
Series repr html only #29383
Changes from 3 commits
a771c97 982a9e1 58628e0 73722b8 4bb34fa a217806 a6e4e89 c08e2ad b245c30 4672ae5 60ec007 18877d9 446ec80 4d40bb6 a1aac92 f61aed2 49fa29b 7a270cb File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -1586,6 +1586,58 @@ def __repr__(self): | |
| | ||
| return result | ||
| | ||
| def _repr_html_(self): | ||
| # TODO: Full independent HTML generation in SeriesFormatter, rather | ||
| # than depending on a limited subset of functionality via to_frame(). | ||
| | ||
| if get_option("display.notebook_repr_html"): | ||
| max_rows = get_option("display.max_rows") | ||
| min_rows = get_option("display.min_rows") | ||
| max_cols = get_option("display.max_columns") | ||
| show_dimensions = get_option("display.show_dimensions") | ||
| | ||
| formatter = fmt.DataFrameFormatter( | ||
big-o marked this conversation as resolved. Show resolved Hide resolved | ||
| self.to_frame(), | ||
| columns=None, | ||
| col_space=None, | ||
| na_rep="NaN", | ||
| formatters=None, | ||
| float_format=None, | ||
| sparsify=None, | ||
| justify=None, | ||
| index_names=True, | ||
| header=False, | ||
| index=True, | ||
| bold_rows=True, | ||
| escape=True, | ||
| max_rows=max_rows, | ||
| min_rows=min_rows, | ||
| max_cols=max_cols, | ||
| show_dimensions=False, # We do this later for a series. | ||
| decimal=".", | ||
| table_id=None, | ||
| render_links=False, | ||
| ) | ||
| html = formatter.to_html(notebook=True).split("\n") | ||
| Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this approach drastically different than what was proposed in #27228 ? Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really, the only difference is in using the Formatter class rather than just invoking it via Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we would prefer to define a SeriesFormatter that inherits a common base class with DataFrameFormatter (callit GenericFromatter). This should't be much more complicated and would be way less fragile than this. | ||
| | ||
| # Find out where the column ends - we will insert footer information here. | ||
| tbl_end = [ | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @big-o I think would be better on this PR if you can do this inside of DataFrameFormatter in its construction itself, rather than 'finding' then end later. is this possible? Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean adding an extra | ||
| rownum for (rownum, row) in enumerate(html) if "</table>" in row | ||
| ][-1] | ||
| | ||
| footer = [] | ||
| if self.name is not None: | ||
| footer.append("Name: <b>{name}</b>".format(name=self.name)) | ||
| if show_dimensions: | ||
| footer.append("Length: {rows}".format(rows=len(self))) | ||
| footer.append("dtype: <tt>{dtype}</tt>".format(dtype=self.dtype)) | ||
| | ||
| html.insert(tbl_end + 1, "<p>{footer}</p>".format(footer=", ".join(footer))) | ||
| Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would this still insert paragraph tags when no footer is required at all? Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but a footer will always be required so there's no need to check I've merged in the latest master and all CI checks pass now. | ||
| | ||
| return "\n".join(html) | ||
| else: | ||
| return None | ||
| | ||
| def to_string( | ||
| self, | ||
| buf=None, | ||
| | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -1868,6 +1868,33 @@ def test_repr_html(self, float_frame): | |
| | ||
| tm.reset_display_options() | ||
| | ||
| def test_repr_html_series(self): | ||
| data = [1, "two", 3.1, -4.2, True, np.nan] | ||
| | ||
| fmt.set_option("display.max_rows", len(data)) | ||
| | ||
| small = pd.Series(data, name="test series") | ||
| sm_html = small._repr_html_() | ||
| | ||
| for val in data: | ||
| if pd.isnull(val): | ||
| assert "<td>NaN</td>" in sm_html | ||
| else: | ||
| assert "<td>{}</td>".format(val) in sm_html | ||
| | ||
| assert "<p>Name: <b>{}</b>".format(small.name) in sm_html | ||
| ||
| assert "Length: {}".format(len(small)) in sm_html | ||
| assert "dtype: <tt>{}</tt>".format(small.dtype) in sm_html | ||
| | ||
| large = small.repeat(1000) | ||
| large.name = None | ||
| lg_html = large._repr_html_() | ||
| | ||
| assert "<td>...</td>" in lg_html | ||
| assert "<p>Name: <b>" not in lg_html | ||
| | ||
| tm.reset_display_options() | ||
| | ||
| def test_repr_html_mathjax(self): | ||
| df = DataFrame([[1, 2], [3, 4]]) | ||
| assert "tex2jax_ignore" not in df._repr_html_() | ||
| | ||
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.
As a follow up I think should put this in the NDFrame superclass shared by DataFrame and Series rather than copy paste