messytables
repository·master·Indexed 18 days ago
https://github.com/okfn/messytablesA Python library for parsing messy tabular data. It provides tools to automatically detect headers and guess data types across various file formats, including CSV, XLS, XLSX, HTML, and ZIP. The library uses a system of stream processors registered to a RowSet to clean and transform inconsistent datasets, with support for exporting processed data to the JSON Table Schema format.
What's inside messytables
- messytables is a Python library designed to handle messy tabular data across various formats. Its primary capabilities include guessing data types and detecting table headers automatically, making it useful for processing unstructured or semi-structured tabular datasets.
How stream processors work in messytables
masterStream processors are functions used to apply transformations to a
RowSetduring iteration. To use one, you callrow_set.register_processor(processor_function).A processor is a function that takes two arguments:
- The
RowSet. - The current row (a list of
Cellobjects).
The processor must return:
- A modified version of the row (a list of
Cellobjects). Noneto indicate that the row should be dropped from the iteration.
Commonly used processors (often implemented as closures) include:
types_processor: Applies guessed column types to rows.offset_processor: Skips a specific number of rows.null_processor: Handles null values.headers_processor: Applies guessed header names to cells.
- The
Core entities: Cell, TableSet, and RowSet
masterMessytables uses three primary abstractions to represent tabular data:
Cell: Represents a single data point. It contains thevalue, thecolumnname, and thetype(CellType).TableSet: A collection of tables (e.g., multiple sheets in an Excel workbook).RowSet: An iterator over the rows of a single table. It provides a.samplefor peeking at data and a.register_processor()method to apply transformations. Note that aRowSetcan only be iterated over once.
Common
TableSetimplementations include:CSVTableSet: For CSV files (uses Python's dialect sniffer).XLSTableSet: For Microsoft Excel 2003 format.XLSXTableSet: For XML-based Excel format.HTMLTableSet: For HTML documents (requireslxml).ZIPTableSet: For loading CSV or Excel files from within ZIP archives.
Parse messy tabular data with messytables
masterMessytables is designed to handle poorly formatted tabular data, such as CSVs with text fragments before the header, or files where column types are not explicitly defined. It uses a toolbox of independent heuristic methods (processors) that you register to a
RowSetto clean and transform data during iteration.To process a file:
- Load it using a specific
TableSet(e.g.,CSVTableSet) or useany_tablesetto auto-detect the format. - Access a
RowSetfrom thetablescollection. - Use
row_set.sampleto peek at data for guessing headers or types. - Register processors (like
headers_processor,offset_processor, ortypes_processor) to theRowSetto apply transformations. - Iterate over the
RowSetto get cleaned data.
from messytables import CSVTableSet, type_guess, \\ types_processor, headers_guess, headers_processor, \\ offset_processor, any_tableset fh = open('messy.csv', 'rb') # Load a file object table_set = CSVTableSet(fh) # A table set is a collection of tables: row_set = table_set.tables[0] # A row set is an iterator; use .sample to peek at data print row_set.sample.next() # 1. Guess header names and the offset of the header offset, headers = headers_guess(row_set.sample) row_set.register_processor(headers_processor(headers)) # 2. Skip the header rows (add 1 to begin with content, not the header) row_set.register_processor(offset_processor(offset + 1)) # 3. Guess column types types = type_guess(row_set.sample, strict=True) # 4. Apply these types to each row during iteration row_set.register_processor(types_processor(types)) # 5. Run operations on the cleaned data for row in row_set: do_something(row)- Load it using a specific
Convert RowSets to JSON Table Schema
masterMessytables can export its processed data and metadata to the JSON Table Schema format using the following methods:
rowset_as_jts(row_set)headers_and_typed_as_jts(row_set)
Detect column types with type_guess
masterThe
type_guessfunction performs brute-force type detection by attempting to convert column members into various types and finding the best match. This is useful for CSV data where type information is missing.Supported Types:
StringTypeIntegerTypeFloatTypeDecimalTypeBoolTypeDateTypeDateUtilType
from messytables import type_guess # types = type_guess(sample, strict=True) # strict=True ensures a more rigorous matchDetect headers with headers_guess
masterBecause many tabular files contain titles or metadata in the first few rows,
headers_guessscans the initial rows of aRowSetto determine which row actually contains the column headers and what those header names are.from messytables import headers_guess # offset, headers = headers_guess(row_set.sample) # offset: the integer index where the header is located # headers: the list of header names