Skip to content

Commit e0bd394

Browse files
jnothmanjreback
authored andcommitted
ENH Avoid redundant CSS in Styler.render (#30876)
1 parent 15bacea commit e0bd394

File tree

4 files changed

+24
-7
lines changed

4 files changed

+24
-7
lines changed

doc/source/whatsnew/v1.1.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Enhancements
1818
Other enhancements
1919
^^^^^^^^^^^^^^^^^^
2020

21+
- :class:`Styler` may now render CSS more efficiently where multiple cells have the same styling (:issue:`30876`)
2122
-
2223
-
2324

pandas/io/formats/style.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def format_attr(pair):
286286
clabels = [[x] for x in clabels]
287287
clabels = list(zip(*clabels))
288288

289-
cellstyle = []
289+
cellstyle_map = defaultdict(list)
290290
head = []
291291

292292
for r in range(n_clvls):
@@ -408,12 +408,17 @@ def format_attr(pair):
408408
for x in ctx[r, c]:
409409
# have to handle empty styles like ['']
410410
if x.count(":"):
411-
props.append(x.split(":"))
411+
props.append(tuple(x.split(":")))
412412
else:
413-
props.append(["", ""])
414-
cellstyle.append({"props": props, "selector": f"row{r}_col{c}"})
413+
props.append(("", ""))
414+
cellstyle_map[tuple(props)].append(f"row{r}_col{c}")
415415
body.append(row_es)
416416

417+
cellstyle = [
418+
{"props": list(props), "selectors": selectors}
419+
for props, selectors in cellstyle_map.items()
420+
]
421+
417422
table_attr = self.table_attributes
418423
use_mathjax = get_option("display.html.use_mathjax")
419424
if not use_mathjax:

pandas/io/formats/templates/html.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
{% block before_cellstyle %}{% endblock before_cellstyle %}
1515
{% block cellstyle %}
1616
{%- for s in cellstyle %}
17-
#T_{{uuid}}{{s.selector}} {
17+
{%- for selector in s.selectors -%}{%- if not loop.first -%},{%- endif -%}#T_{{uuid}}{{selector}}{%- endfor -%} {
1818
{% for p,val in s.props %}
1919
{{p}}: {{val}};
2020
{% endfor %}

pandas/tests/io/formats/test_style.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,19 @@ def test_empty(self):
472472

473473
result = s._translate()["cellstyle"]
474474
expected = [
475-
{"props": [["color", " red"]], "selector": "row0_col0"},
476-
{"props": [["", ""]], "selector": "row1_col0"},
475+
{"props": [("color", " red")], "selectors": ["row0_col0"]},
476+
{"props": [("", "")], "selectors": ["row1_col0"]},
477+
]
478+
assert result == expected
479+
480+
def test_duplicate(self):
481+
df = pd.DataFrame({"A": [1, 0]})
482+
s = df.style
483+
s.ctx = {(0, 0): ["color: red"], (1, 0): ["color: red"]}
484+
485+
result = s._translate()["cellstyle"]
486+
expected = [
487+
{"props": [("color", " red")], "selectors": ["row0_col0", "row1_col0"]}
477488
]
478489
assert result == expected
479490

0 commit comments

Comments
 (0)