Exporting large pandas DataFrames to LaTeX can sometimes be tricky—especially when you want multi-page tables (longtable) combined with custom styling like bold headers or index labels. A common issue arises where CSS formatting works seamlessly with standard tables, but breaks down into invalid syntax like \font-weightbold when toggling environment="longtable".

Understanding the Problem: Why \font-weightbold Appears

In pandas, the Styler.to_latex() method supports converting CSS styles into LaTeX commands using the convert_css=True argument. Under normal conditions (using a standard tabular environment), pandas converts CSS like font-weight: bold; into LaTeX's \bfseries.

However, when setting environment="longtable", certain versions of pandas experience a parsing glitch where the CSS-to-LaTeX converter fails to interpret the CSS property correctly inside the repeated header/footer blocks of longtable. Instead of outputting \bfseries, it dumps the raw CSS string into a malformed command: \font-weightbold.

Solution 1: Format Headers and Indices Directly in the DataFrame (Recommended)

The cleanest and most reliable workaround is to format the strings directly as LaTeX before passing them to the Styler. This completely bypasses the CSS-to-LaTeX conversion layer, ensuring your document compiles reliably regardless of your pandas version.

import pandas as pd

# Sample DataFrame
data = {
    ("raw count", "False"): [55039, 53592],
    ("raw count", "True"): [14887, 15172],
    ("sum of weights", "False"): [126900099, 186545780],
    ("sum of weights", "True"): [28367901, 57685123]
}
index = pd.Index([1980, 2018], name="year")
df = pd.DataFrame(data, index=index)
df.columns.names = ["", "retiree"]

# 1. Format index and column labels directly with LaTeX \textbf{}
df.index = df.index.map(lambda x: f"\\textbf{{{x}}}")
df.columns = df.columns.map(lambda col: tuple(f"\\textbf{{{c}}}" for c in col))

# 2. Export using Styler with escape=False to preserve LaTeX commands
styler = df.style.format(precision=0, thousands=",", escape="latex")
latex_code = styler.to_latex(
    environment="longtable",
    hrules=True
)

# Save to file
with open('sample_sizes.tex', 'w') as f:
    f.write(latex_code)

Solution 2: Post-Processing the Exported LaTeX String

If you prefer keeping your DataFrame unmodified and using map_index or CSS rules, you can simply correct the malformed tag by doing a string replacement on the exported LaTeX output before writing it to disk:

styler = df.style.format(precision=0, thousands=",", escape="latex")
styler.map_index(lambda v: "font-weight: bold;", axis="index")
styler.map_index(lambda v: "font-weight: bold;", axis="columns")

# Generate LaTeX output with CSS conversion enabled
latex_output = styler.to_latex(convert_css=True, hrules=True, environment="longtable")

# Fix the parsing bug via string replacement
latex_output = latex_output.replace(r"\font-weightbold ", r"\bfseries ")

# Save output
with open('sample_sizes.tex', 'w') as f:
    f.write(latex_output)

Solution 3: Updating Pandas

The CSS-to-LaTeX conversion in Styler.to_latex() has received numerous bug fixes across recent releases. If you are using an older version of pandas (prior to 2.0.0), updating to the latest stable version may resolve table rendering inconsistencies:

pip install --upgrade pandas jinja2

LaTeX Setup Note

Remember that when using environment="longtable" and hrules=True, your LaTeX document preamble must include the following packages:

\usepackage{longtable}
\usepackage{booktabs}

Conclusion

While pandas' CSS-to-LaTeX converter is convenient, it can produce invalid output with specialized environments like longtable. Formatting the index and columns directly with \textbf{} or applying a quick regex/string replacement provides a robust, compile-ready LaTeX export every time.