Skip to main content
Last month you successfully ingested July’s orders. This month’s August orders arrived from multiple humans and systems — and of course some rows look a little off: missing customer IDs, non-existent customers, strange product IDs, negative quantities, and malformed dates. Manual line-by-line fixes aren’t feasible at scale. In this lesson we cover practical, repeatable data cleaning using pandas. We’ll focus on common dirty-data patterns (missing values, invalid types, duplicates, mismatched foreign keys), the three levels of validation (column, row, table), and a pragmatic strategy: drop rows that fail validation while logging everything dropped so it can be reviewed and corrected later.
The image shows a person standing next to a presentation slide with a cartoon dog and text discussing data validation concepts.

High-level plan

  1. Load orders, customers, and products tables.
  2. Keep a raw copy of the orders data for auditing and possible re-ingestion.
  3. Row-level checks: missing required fields, invalid dates, invalid numeric values, duplicates.
  4. Table-level checks: foreign keys (customer_id, product_id) must exist in lookup tables.
  5. Log and save dropped rows for auditing.
  6. Save cleaned dataset and update ingestion logs.
Before you start, activate your environment and ensure pandas is installed. This process is repeatable and should be run as part of your ETL pipeline. Use the raw copy of the incoming file for traceability and audits.

Initial setup — prepare folders and find the orders file

Create required folders, locate the orders CSV (any filename containing orders), and load an ingest log if present.

Pipeline policy: drop-and-log

For this lesson the pipeline policy is to drop rows that fail validation and log them. Dropping is acceptable when only a small fraction of rows are bad and when you retain the dropped rows for later review or repair.
Dropping rows can bias downstream analytics if many rows are removed. Always log discarded rows and their reasons so the data owner can correct the source or you can implement targeted fixes later.

Load the datasets and save a raw copy

Row-level checks — what to validate

Below is a concise summary of common checks and the typical remediation action.

1) Missing required columns / missing values

Decide which columns are mandatory. If a required column is missing from the file entirely, you should either raise an error or log and skip processing (depending on your pipeline policy). Here we assume the columns exist and drop rows with nulls in required fields.

2) Invalid dates

Use pandas to parse dates. errors='coerce' converts unparsable values to NaT, which you can then drop. If you require strict formats, pass a format= argument.
The image shows a person standing next to a screenshot of a Jupyter Notebook interface with Python code aimed at cleaning data through row-level and table-level checks. The code involves dropping rows with missing data and invalid entries.
Tip: to avoid accepting time-only strings like "10:45", either validate the parsed timestamp’s date components (year/month/day) or use a strict format parameter. See pandas docs: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html

3) Numeric fields: customer_id, product_id, quantity

Coerce numeric fields and drop rows that fail numeric validation. For quantity, enforce strictly positive values (> 0). For IDs, require non-negative integers. Use temporary checked columns during validation and remove them afterwards.
Note: If you must disallow fractional IDs, check that the checked numeric values equal their integer cast before accepting them; astype(int) will silently truncate floats.

4) Duplicates

Remove exact duplicate rows (or duplicates by order_id if that’s your unique key). Make sure any helper columns that could affect duplicate detection are dropped before running this check.

Table-level checks — foreign keys

Verify that customer_id and product_id exist in their respective lookup tables. Make sure lookup key dtypes match (both int or both string) to avoid false negatives.

Cross-checks and saving dropped rows for audit

Compare the raw copy to the cleaned dataframe to extract and save exactly what was removed during cleaning. This creates an auditable CSV that the data owner can inspect and use to fix source issues.

Final tidy-up, save cleaned data, archive raw file, update log

Remove any temporary helper columns, reset the index, save the cleaned file to insights/, archive the original raw file, and append an entry to the ingest log.

Example observations (illustrative)

  • Missing data: rows with IDs 1035 and 1050 were dropped.
  • Invalid dates: entries like “10:45” (time-only) were dropped.
  • Invalid numbers: negative quantity or fractional IDs were removed.
  • Duplicate rows: order ID 1072 appeared twice; one duplicate was removed.
  • Missing foreign keys: orders referencing customer_id = 999 or product_id = 999 were dropped because those IDs don’t exist in the lookup tables.
The image shows a person standing in front of a virtual background displaying a spreadsheet with order details, including columns for order ID, customer ID, product ID, quantity, and order date.
When you open the cleaned file you should see the dirty rows removed. The cleaned dataset is now ready for the next step in your pipeline: enrichment, aggregation, and analytics.

Recap — three levels of validation

Dirty data comes in many shapes: missing values, invalid formats (dates), negative or non-integer numbers, duplicates, or mismatched foreign keys. Apply validation at these three levels:
  • Column-level: Are required columns present, and are their dtypes sensible?
  • Row-level: Are the values in each row complete and valid?
  • Table-level: Do foreign keys match values in lookup tables?
The image shows a man standing beside text boxes listing different forms of dirty data and levels of data validation. The text includes points on missing values, invalid formats, and validation at column, row, and table levels.
Cleaning often means dropping bad rows, but always log what you discard so errors can be traced back and fixed.
The image shows a person speaking, with the text "Cleaning can mean dropping bad rows, but always log what you discard for transparency or fixing." The KodeKloud logo is on the person's shirt.

Next steps and practice

Apply these techniques on sample files and iterate on rules that reflect your business requirements. Consider the following improvements over time:
  • Soft-fail: flag and route suspicious rows for manual review instead of immediate deletion.
  • Auto-repair: implement deterministic fixes (e.g., common date format corrections) with confidence scoring.
  • Schema enforcement: use tools like Great Expectations, Apache Deequ, or declarative schemas to codify checks.
  • Monitoring: track dropped-row counts over time to detect upstream regressions.
Links and references Practice these techniques with a hands-on exercise to build a robust, auditable cleaning step in your ETL pipeline.

Watch Video