Skip to main content

A library to process raw data into a structured format

Project description

⚗️ Zeolite


Zeolite is a Python library that uses a simple configuration approach to define a table/schema structure. Raw data can normalised, cleaned, and validated against the schema in a performant and standardised way.

The schema implements a multi-stage pipeline:

  • normalise - Normalises the dataset to ensure column headers align with the defined schema/column definitions
  • coerce - Coerces the data types of the columns in the dataset to match the defined schema/column definitions
  • prepare - Appends new columns to the dataset representing cleaned & derived/calculated columns and check/validation columns based on the validation rules
  • validate - Applies validation rules/thresholds to the dataset, captures errors and determines if the dataset as a whole should be rejected
  • filter - Drops rows that have failed checks based on the remove_row_on_fail argument
  • refine - Renames working columns, and drops unneeded column to refine the dataset to the final structure

The final datasets are guaranteed to be in the correct format and can be easily exported to a variety of formats. In addition, Zeolite captures errors and warnings during the processing of the data, which can be used to improve the quality of the data.

Example

First we define a data schema that describes how our data should be, and includes both structural definitions, cleaning functions, and validation/data quality checks

import zeolite as z

data_schema = z.schema("individual").columns(
    z.col.str("id")
    .clean(z.Clean.id(prefix="ORG_X"))
    .validations(
        z.Check.not_empty(
            warning="any", 
            error=0.1, 
            treat_empty_strings_as_null=True, 
            remove_row_on_fail=True
        ),
        z.Check.unique(check_on_cleaned=True, reject="any"),
    ),

    z.col.str("birthdate")
    .clean(z.Clean.date())
    .validations(z.Check.valid_date(reject="all")),

    z.col.str("gender").clean(
        z.Clean.enum(
            sanitise="lowercase",
            enum_map={
                "m": "Male", "male": "Male",
                "f": "Female", "female": "Female",
                "d": "Gender Diverse", "diverse": "Gender Diverse"
            },
        )
    ),

    z.col.str("is_active").clean(
        z.Clean.boolean(
            true_values={"yes", "active"}, false_values={"no", "inactive"}
        )
    ),

    z.col.str("ethnicity").clean(z.Clean.sanitised_string()),
    z.col.str("ethnicity_2").clean(z.Clean.sanitised_string()),
    z.col.derived(
        "is_maori",
        function=(
                z.ref("ethnicity").clean().col.eq("maori")
                | z.ref("ethnicity_2").clean().col.eq("maori")
        ),
        data_type="boolean",
    ),
)

Once we have the schema defined, we can apply it against our Polars DataFrame/LazyFrame

import polars as pl

df = pl.DataFrame({
    # the third row will be removed because the empty string is treated as null 
    # and our `Check.not_empty` has `remove_row_on_fail=True`
    "id":["1","2","","4"],
   
    # we can handle multiple date formats (including weird Excel dates!)
    "birthdate":["1970-01-01","33746","","1987-01-25T00:00:00Z"],
    
    # using our enum_map, we can collapse category variants to a common definition
    "gender":["Male"," Male "," F ","d"],
    
    # boolean fields can be coerced from categories/values as well as bools
    "is_active":["active","inactive",None,"true"],
    
    # sanitising these fields means that we can match e.g. 'maori' more accurately
    "ethnicity":["Maori","Pakeha",None,"Asian"],
    "ethnicity_2":[None,"Māori ",None,"maori"],
})

res = data_schema.apply(df)

The .apply(...) method returns a result - either a ProcessingFailure or a ProcessingSuccess. These can be differentiated with a simple check on the success attribute:

if res.success:
    # Do stuff with the data (LazyFrame) on success
    clean_df = res.data.collect()
else:
    # Gracefully handle failures
    failed_stage = res.failed_stage
    
# Regardless of the result, we have access to all the errors 
# that occurred during processing, which we can use for 
# logging/data quality reports  
errors = res.errors
for e in errors:
    print(e.message)

# We can also examine the snapshot data at each stage if necessary
# This is particularly useful to capture & debug working data!
if res.prepared is not None:
    prepared_df = res.prepared.collect()
    
if res.validated is not None:
    validated_df = res.validated.collect()

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

zeolite-0.2.2.tar.gz (114.4 kB view details)

Uploaded Source

Built Distribution

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

zeolite-0.2.2-py3-none-any.whl (75.8 kB view details)

Uploaded Python 3

File details

Details for the file zeolite-0.2.2.tar.gz.

File metadata

  • Download URL: zeolite-0.2.2.tar.gz
  • Upload date:
  • Size: 114.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.3

File hashes

Hashes for zeolite-0.2.2.tar.gz
Algorithm Hash digest
SHA256 13dc3a91d60660e71a40e6da1d3c938f4dfce21e445f336816ac2cbb0d4e2513
MD5 cb7261f2cb6708e32f728107895e0a99
BLAKE2b-256 cfec4bb6769aef78f20e45e23ae7f7176f1d5b8f4257df3e52fc7fb99e27c0e3

See more details on using hashes here.

File details

Details for the file zeolite-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: zeolite-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 75.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.3

File hashes

Hashes for zeolite-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b4635a71edb6b9dc9e7d68ae0b02b8181dd866f245035fe27f96c8db6b3d4fde
MD5 04525b06998a90d82bef33fd2c8fa975
BLAKE2b-256 c85f7edc60e3f00befcae0f90255a8dcb09e478587964b7e71c9e78d05b631d3

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