Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ or `showindex=False`. To add a custom row index column, pass

```

With `headers="firstrow"`, hiding a DataFrame's row index also omits its
first index value from the header.

### Table format

There is more than one way to format a table in plain text. The third
Expand Down
4 changes: 3 additions & 1 deletion tabulate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,7 @@ def _normalize_tabular_data(tabular_data, headers, showindex="default"):
headers = list(map(str, range(len(rows[0]))))

# take headers from the first row if necessary
index_header_from_firstrow = headers == "firstrow" and index is not None
if headers == "firstrow" and len(rows) > 0:
if index is not None:
headers = [index[0]] + list(rows[0])
Expand Down Expand Up @@ -1602,7 +1603,8 @@ def _normalize_tabular_data(tabular_data, headers, showindex="default"):
index = list(range(len(rows)))
rows = _prepend_row_index(rows, index)
elif showindex == "never" or (not _bool(showindex) and not showindex_is_a_str):
pass
if index_header_from_firstrow:
headers = headers[1:]

# pad with empty headers for initial columns if necessary
headers_pad = 0
Expand Down
38 changes: 38 additions & 0 deletions test/test_dataframe_firstrow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""First-row headers must respect whether the DataFrame index is shown."""

import pytest

from tabulate import tabulate


@pytest.mark.parametrize("tablefmt", ["simple", "grid", "html"])
@pytest.mark.parametrize("row_count", [0, 1, 2])
@pytest.mark.parametrize("showindex", [False, "never"])
def test_dataframe_firstrow_without_index(tablefmt, row_count, showindex):
pandas = pytest.importorskip("pandas")
rows = [["Name", "Age"]] + [[f"Person {i}", i] for i in range(row_count)]
frame = pandas.DataFrame(rows, index=["row label"] + list(range(row_count)))

assert tabulate(frame, headers="firstrow", showindex=showindex, tablefmt=tablefmt) == tabulate(
rows, headers="firstrow", tablefmt=tablefmt
)


@pytest.mark.parametrize("showindex", [True, "always", "default"])
def test_dataframe_firstrow_with_index(showindex):
pandas = pytest.importorskip("pandas")
frame = pandas.DataFrame([["Name", "Age"], ["Alice", 30]], index=["row label", "first"])

assert tabulate(frame, headers="firstrow", showindex=showindex) == tabulate(
[["row label", "Name", "Age"], ["first", "Alice", 30]], headers="firstrow"
)


def test_dataframe_firstrow_numpy_false():
numpy = pytest.importorskip("numpy")
pandas = pytest.importorskip("pandas")
rows = [["Name", "Age"], ["Alice", 30]]

assert tabulate(
pandas.DataFrame(rows), headers="firstrow", showindex=numpy.bool_(False)
) == tabulate(rows, headers="firstrow")