Skip to main content

Heuristic header row range detection for Excel-like two-dimensional data.

Project description

guess-sheet-headers

中文文档

guess-sheet-headers is a small heuristic Python package for guessing the header row range of Excel-like two-dimensional data. It is designed for practical automation, not perfect spreadsheet understanding.

The input is a two-dimensional list-like object. The output is a (start, end) tuple using zero-based, left-closed/right-open row indexes. (0, 0) means no reliable header was detected.

from datetime import date
from guess_sheet_headers import do_guess

rows = [
    ["姓名", "金额", "日期"],
    ["张三", 10, date(2026, 1, 1)],
    ["李四", 20, date(2026, 1, 2)],
]

assert do_guess(rows) == (0, 1)

Install

For local development:

python -m pip install -e .

The package has no runtime dependencies.

Algorithm

The default heuristic is intentionally simple and works in two stages: first find a suspected data region, then decide how many rows above it should be kept as the header range.

  1. Sample at most 200 rows.
  2. If total rows are at most 200, use all rows.
  3. Otherwise sample the first 100 rows, 50 middle rows, and 50 tail rows, then remove duplicate indexes.
  4. Before sampling, trim all-empty columns at the left and right edges and all-empty rows at the bottom. Top empty rows, middle empty rows, and middle empty columns are kept.
  5. Convert cells to integer types.
  6. For each column, count all types including EMPTY.
  7. Keep at most three types whose per-column ratio is greater than 30%; if none exceed 30%, the column profile is an empty set.
  8. All column type sets form the data-region profile.
  9. Scan top rows. The first row whose score is greater than 0.9 is treated as the suspected first data row.
  10. In the suspected header area before that row, find the row with the highest text density, where text density is (PHRASE + SENTENCE) / column_count and empty cells stay in the denominator.
  11. Return (0, best_header_row + 1) so merged-cell titles and notes above the field row remain part of the header range. If the first row already matches data, return one default header row.

The match score is:

sum(column_weight) / column_count

Column weights:

type is in column profile: 1.0
otherwise: 0.0
empty profile set: skipped, not included in denominator

Cell Types

Cell types are plain integers:

EMPTY = 0
NUMBER = 1
DATETIME = 2
NUMERIC_STR = 3
PHRASE = 4
SENTENCE = 5

Notes:

DATETIME is used only when the parser has already returned a Python datetime, date, or time object.

NUMERIC_STR is used for strings that contain digits plus numeric separators or symbols, such as +25.3 or 2026/3/7.

PHRASE is short text. SENTENCE is longer natural-language text. For ASCII text, the rule splits by whitespace and punctuation except - and _; more than one segment is a sentence. For non-ASCII text, more than 8 non-space characters is a sentence.

Configuration

Use GuessOptions to tune thresholds and sample sizes:

from guess_sheet_headers import GuessOptions, do_guess

options = GuessOptions(
    match_threshold=0.9,
    col_type_threshold=0.3,
    min_sample_rows=10,
)

result = do_guess(rows, options)

Limitations

This is a guessing algorithm for common structured tables, not a strict Excel understanding engine. It intentionally favors simple, predictable behavior over exhaustive edge-case handling.

Known weak cases include very small sheets, sparse data rows, heavily mixed column types, multiple unrelated tables in one sheet, long title/description blocks before the table, and sheets where group headers have many empty cells that match a sparse data profile.

Development

Run tests from this directory:

python -m unittest discover -s tests

License

MIT License. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

guess_sheet_headers-0.1.0.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

guess_sheet_headers-0.1.0-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file guess_sheet_headers-0.1.0.tar.gz.

File metadata

  • Download URL: guess_sheet_headers-0.1.0.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for guess_sheet_headers-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9fedbeaca28a6feea450635dcbb1e01068dea3bb38134af600b432ed258e7489
MD5 1938baff6af8a84d16979d85442c48ba
BLAKE2b-256 4435813d29fc779271bb9cfe134c97c683ca12f966c3b6e1b1ecaf9751df6ed5

See more details on using hashes here.

File details

Details for the file guess_sheet_headers-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for guess_sheet_headers-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ab80a0375b5eaec7037d740979462f66c503b4d6711b9d65259abaa325fef11
MD5 6c9a2cfb4d1c96e4479182c52de8cb9d
BLAKE2b-256 ef6505081a4826b494635f2ad3b707dd1180ac0a4072057ebd7ab9b46d432cd9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page