Skip to content

Commit 2cd6489

Browse files
authored
feat: Add dataframe.to_html (#259)
Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://togithub.com/googleapis/python-bigquery-dataframes/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes b/296945119
1 parent 0e1bbfc commit 2cd6489

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

bigframes/dataframe.py

+52
Original file line numberDiff line numberDiff line change
@@ -2682,6 +2682,58 @@ def to_string(
26822682
encoding,
26832683
)
26842684

2685+
def to_html(
2686+
self,
2687+
buf=None,
2688+
columns: Sequence[str] | None = None,
2689+
col_space=None,
2690+
header: bool = True,
2691+
index: bool = True,
2692+
na_rep: str = "NaN",
2693+
formatters=None,
2694+
float_format=None,
2695+
sparsify: bool | None = None,
2696+
index_names: bool = True,
2697+
justify: str | None = None,
2698+
max_rows: int | None = None,
2699+
max_cols: int | None = None,
2700+
show_dimensions: bool = False,
2701+
decimal: str = ".",
2702+
bold_rows: bool = True,
2703+
classes: str | list | tuple | None = None,
2704+
escape: bool = True,
2705+
notebook: bool = False,
2706+
border: int | None = None,
2707+
table_id: str | None = None,
2708+
render_links: bool = False,
2709+
encoding: str | None = None,
2710+
) -> str:
2711+
return self.to_pandas().to_html(
2712+
buf,
2713+
columns, # type: ignore
2714+
col_space,
2715+
header,
2716+
index,
2717+
na_rep,
2718+
formatters,
2719+
float_format,
2720+
sparsify,
2721+
index_names,
2722+
justify, # type: ignore
2723+
max_rows,
2724+
max_cols,
2725+
show_dimensions,
2726+
decimal,
2727+
bold_rows,
2728+
classes,
2729+
escape,
2730+
notebook,
2731+
border,
2732+
table_id,
2733+
render_links,
2734+
encoding,
2735+
)
2736+
26852737
def to_markdown(
26862738
self,
26872739
buf=None,

tests/system/small/test_dataframe.py

+9
Original file line numberDiff line numberDiff line change
@@ -3463,6 +3463,15 @@ def test_df_to_string(scalars_df_index, scalars_pandas_df_index):
34633463
assert bf_result == pd_result
34643464

34653465

3466+
def test_df_to_html(scalars_df_index, scalars_pandas_df_index):
3467+
unsupported = ["numeric_col"] # formatted differently
3468+
3469+
bf_result = scalars_df_index.drop(columns=unsupported).to_html()
3470+
pd_result = scalars_pandas_df_index.drop(columns=unsupported).to_html()
3471+
3472+
assert bf_result == pd_result
3473+
3474+
34663475
def test_df_to_markdown(scalars_df_index, scalars_pandas_df_index):
34673476
# Nulls have bug from tabulate https://github.com/astanin/python-tabulate/issues/231
34683477
bf_result = scalars_df_index.dropna().to_markdown()

third_party/bigframes_vendored/pandas/core/frame.py

+124
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,130 @@ def to_string(
685685
"""
686686
raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE)
687687

688+
def to_html(
689+
self,
690+
buf=None,
691+
columns: Sequence[str] | None = None,
692+
col_space=None,
693+
header: bool = True,
694+
index: bool = True,
695+
na_rep: str = "NaN",
696+
formatters=None,
697+
float_format=None,
698+
sparsify: bool | None = None,
699+
index_names: bool = True,
700+
justify: str | None = None,
701+
max_rows: int | None = None,
702+
max_cols: int | None = None,
703+
show_dimensions: bool = False,
704+
decimal: str = ".",
705+
bold_rows: bool = True,
706+
classes: str | list | tuple | None = None,
707+
escape: bool = True,
708+
notebook: bool = False,
709+
border: int | None = None,
710+
table_id: str | None = None,
711+
render_links: bool = False,
712+
encoding: str | None = None,
713+
):
714+
"""Render a DataFrame as an HTML table.
715+
716+
**Examples:**
717+
718+
>>> import bigframes.pandas as bpd
719+
>>> bpd.options.display.progress_bar = None
720+
721+
>>> df = bpd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
722+
>>> print(df.to_html())
723+
<table border="1" class="dataframe">
724+
<thead>
725+
<tr style="text-align: right;">
726+
<th></th>
727+
<th>col1</th>
728+
<th>col2</th>
729+
</tr>
730+
</thead>
731+
<tbody>
732+
<tr>
733+
<th>0</th>
734+
<td>1</td>
735+
<td>3</td>
736+
</tr>
737+
<tr>
738+
<th>1</th>
739+
<td>2</td>
740+
<td>4</td>
741+
</tr>
742+
</tbody>
743+
</table>
744+
745+
Args:
746+
buf (str, Path or StringIO-like, optional, default None):
747+
Buffer to write to. If None, the output is returned as a string.
748+
columns (sequence, optional, default None):
749+
The subset of columns to write. Writes all columns by default.
750+
col_space (str or int, list or dict of int or str, optional):
751+
The minimum width of each column in CSS length units. An int is
752+
assumed to be px units.
753+
header (bool, optional):
754+
Whether to print column labels, default True.
755+
index (bool, optional, default True):
756+
Whether to print index (row) labels.
757+
na_rep (str, optional, default 'NaN'):
758+
String representation of NAN to use.
759+
formatters (list, tuple or dict of one-param. functions, optional):
760+
Formatter functions to apply to columns' elements by position or
761+
name.
762+
The result of each function must be a unicode string.
763+
List/tuple must be of length equal to the number of columns.
764+
float_format (one-parameter function, optional, default None):
765+
Formatter function to apply to columns' elements if they are
766+
floats. This function must return a unicode string and will
767+
be applied only to the non-NaN elements, with NaN being
768+
handled by na_rep.
769+
sparsify (bool, optional, default True):
770+
Set to False for a DataFrame with a hierarchical index to print
771+
every multiindex key at each row.
772+
index_names (bool, optional, default True):
773+
Prints the names of the indexes.
774+
justify (str, default None):
775+
How to justify the column labels. If None uses the option from
776+
the print configuration (controlled by set_option), 'right' out
777+
of the box. Valid values are, 'left', 'right', 'center', 'justify',
778+
'justify-all', 'start', 'end', 'inherit', 'match-parent', 'initial',
779+
'unset'.
780+
max_rows (int, optional):
781+
Maximum number of rows to display in the console.
782+
max_cols (int, optional):
783+
Maximum number of columns to display in the console.
784+
show_dimensions (bool, default False):
785+
Display DataFrame dimensions (number of rows by number of columns).
786+
decimal (str, default '.'):
787+
Character recognized as decimal separator, e.g. ',' in Europe.
788+
bold_rows (bool, default True):
789+
Make the row labels bold in the output.
790+
classes (str or list or tuple, default None):
791+
CSS class(es) to apply to the resulting html table.
792+
escape (bool, default True):
793+
Convert the characters <, >, and & to HTML-safe sequences.
794+
notebook (bool, default False):
795+
Whether the generated HTML is for IPython Notebook.
796+
border (int):
797+
A border=border attribute is included in the opening <table>
798+
tag. Default pd.options.display.html.border.
799+
table_id (str, optional):
800+
A css id is included in the opening <table> tag if specified.
801+
render_links (bool, default False):
802+
Convert URLs to HTML links.
803+
encoding (str, default "utf-8"):
804+
Set character encoding.
805+
806+
Returns:
807+
str or None: If buf is None, returns the result as a string. Otherwise
808+
returns None.
809+
"""
810+
raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE)
811+
688812
def to_markdown(
689813
self,
690814
buf=None,

0 commit comments

Comments
 (0)