A 30-Day Data Cleaning Practice Plan
A day-by-day, 30-day plan for practicing data cleaning in 30 to 45 minutes a day: import and profiling, values and types, rows and joins, validation, then a final project.
By Tnas · Published · 8 min read

This 30-day plan builds data cleaning skill in four weekly blocks plus a two-day finish: week 1 covers importing and profiling, week 2 fixes values and types, week 3 handles rows and tables (duplicates, joins, appends, reshaping), and week 4 adds validation, exception reports and reconciliation. Days 29 and 30 are a small end-to-end project. Each day takes 30 to 45 minutes and ends with a checked result, not just code that runs.
The plan works in DuckDB SQL, pandas or a visual pipeline tool. Pick one main tool for the month and use the second one only for the weekly cross-check days.
Key Takeaways
- Spend 30 to 45 minutes a day, and finish every session with a result you can check: an expected output, a reconciled count or a written rule.
- Order matters. Import and profile first, then fix values, then work on rows and tables, then validate. Doing these out of order, for example joining before keys are trimmed, causes avoidable bugs.
- Every seventh day is a review day: redo one earlier task in your second tool and write down what differed.
- Keep a one-line rule log from day 1. By day 30 it becomes the handoff note for your final project.
- Finish with a small public dataset cleaned end to end, so the month ends with something you can show.
How each daily session works
Every day follows the same four steps, so the only new thing each day is the topic:
- Profile (5 minutes). Before reading the task, count rows, look at distinct values and check how missing values appear.
- Solve (20 to 30 minutes). Do the day's exercise in your main tool.
- Check (5 minutes). Compare with the expected result, or reconcile rows in against rows out. A reconciliation is a count check that every input row ended up either in the clean output or in the exceptions.
- Log (5 minutes). Write one sentence per rule you applied, for example: "Blank country becomes missing, not 'Unknown', because the report excludes unknown countries."
The log is easy to skip, but it turns a month of exercises into a set of rules you can explain in an interview or reuse at work. The exercise catalog lists every task by topic and track; the ones named below are free unless marked otherwise.
Week 1: Import and profile before you change anything (days 1–7)
Week 1 is about seeing the data as it really is. Most later mistakes, such as lost leading zeros, numbers parsed as text or blanks treated as zeros, start at import.
| Day | Focus | Practice task |
|---|---|---|
| 1 | Profile a table | Profile any small CSV: row count, distinct values, missing and blank counts per column |
| 2 | Import as text first | Load the same file with type guessing and as text, then compare (example below) |
| 3 | Whitespace and invisible characters | Trim only the characters your policy allows, then count what changed |
| 4 | Missing vs blank vs zero | Exercise: Label unknown categories, keep missing numbers missing |
| 5 | Identifiers and flags | Exercise: Keep identifiers as text and parse yes/no flags |
| 6 | A full first clean | Exercise: Clean an order-line export |
| 7 | Review day | Redo day 6 in your second tool and note every difference |
The guide to profiling a new dataset has a reusable set of profiling queries for day 1. For day 2, this pandas example shows why "import as text first" is a rule rather than a preference:
import pandas as pd
guessed = pd.read_csv("members.csv")
as_text = pd.read_csv("members.csv", dtype=str, keep_default_na=False)
print(guessed)
print(as_text)
print((as_text == "").sum())
With a four-row members.csv containing ids like 000123, postcodes like 02139 and opt-in answers of Y, yes, NA and blank, pandas 3.0 prints:
member_id postcode opted_in
0 123 2139.0 Y
1 124 10001.0 yes
2 125 NaN NaN
3 126 94105.0 NaN
member_id postcode opted_in
0 000123 02139 Y
1 000124 10001 yes
2 000125 NA
3 000126 94105
member_id 0
postcode 1
opted_in 1
dtype: int64
Type guessing turned the member ids into integers, the postcodes into floats with their leading zeros gone, and both the literal text NA and the blank opt-in into the same NaN. Reading everything as text keeps all three distinctions, so you can decide what each one means. The pandas read_csv reference documents keep_default_na, and DuckDB's CSV import documentation covers the equivalent options there. The day 5 exercise, keeping identifiers as text and parsing flags, builds directly on this.
Week 2: Fix values and types (days 8–14)
Week 2 moves column by column. Each task is a single kind of value with a policy you have to apply exactly: dates, money, names, emails and categories.
| Day | Focus | Practice task |
|---|---|---|
| 8 | Dates with a declared locale | Exercise: Parse dates by declared locale |
| 9 | Timestamps and offsets | Exercise: Timestamps need an offset |
| 10 | Names and Unicode | Exercise: Normalize names without changing letters |
| 11 | Emails under a policy | Exercise: Normalize emails under a declared policy |
| 12 | Category mapping | Exercise: Map channels with an approved dictionary |
| 13 | Money and exact decimals | Convert amount text to exact decimals; compare with float totals |
| 14 | Review day | Redo day 8 or 12 in your second tool; add any new rules to your log |
Day 8 is the most important of the week. A date like 03/04/2026 is March 4 in one locale and April 3 in another, and no amount of cleverness recovers the right answer without a declared locale. Practice it with the parse dates by declared locale exercise before anything else involving dates.
On day 13, compare a total computed from floating-point numbers with one computed from exact decimals. The difference is usually tiny, which is exactly why it slips into reports unnoticed.
Week 3: Rows and tables (days 15–21)
Week 3 stops looking at single values and starts asking what a row means. Duplicates, joins and appends all depend on knowing the row grain: what one row is supposed to represent.
| Day | Focus | Practice task |
|---|---|---|
| 15 | Row grain and duplicates | Find the columns that should identify one row; count violations |
| 16 | Survivor rules | Exercise: Pick one surviving record per account |
| 17 | Joins with missing keys | Exercise: Join orders to customers without matching blanks |
| 18 | Orphans and integrity | Exercise: Referential integrity with explicit exceptions |
| 19 | Appending files | Exercise: Append monthly files under a declared schema |
| 20 | Reshaping | Exercise: Unpivot survey answers without inventing scores |
| 21 | Review day | Redo day 17 in your second tool; check row counts before and after every join |
Two tasks this week are easy to get subtly wrong. On day 16, picking a surviving record means applying a stated tie-break order rather than keeping "the first one". On day 17, joining without matching blanks shows that SQL and pandas disagree about missing keys: pandas matches missing keys to each other by default, while a SQL join never matches NULL to NULL. Day 21 is the right moment to see that difference for yourself.
Week 4: Validate, report and reconcile (days 22–28)
Week 4 is what makes cleaning trustworthy. Instead of quietly fixing or dropping rows, you'll write rules, send failures to an exception report with reasons and prove that nothing was lost.
| Day | Focus | Practice task |
|---|---|---|
| 22 | Range rules in order | Exercise: Validate quantities and prices against ranges |
| 23 | Flag, don't delete | Exercise: Flag large transactions, keep refunds |
| 24 | Exception reports | Rewrite one earlier task so every rejected row has a reason column |
| 25 | Reconciliation | Prove rows in = clean rows + exceptions, and totals match, for day 24 |
| 26 | Rerun safely | Run day 24 twice on the same input and confirm the output is identical |
| 27 | Write it up | Turn your rule log into a one-page note: rules, exceptions, open questions |
| 28 | Review day | Redo day 22 in your second tool |
Rule order matters on day 22: a missing quantity and a negative quantity are different problems, and each failing row should get one clear reason. The validate ranges with ordered reasons exercise practices exactly that. For day 25, the reconciliation guide shows how to check sums as well as counts.
Days 29–30: One small end-to-end project
Finish by cleaning one real public dataset from raw file to documented output. Keep the scope to one question and a handful of columns, so two sessions are enough.
- Day 29: pick a dataset with a clear license, profile it, write your questions, and apply the rules your question needs.
- Day 30: reconcile, write a short note covering rules, exceptions and what you didn't fix, and save the code so it runs again from the raw file.
A list of free messy datasets for practice with checked licenses is a good place to choose from, and data cleaning projects for beginners has scoped project ideas if you want more structure.
How to adjust the plan
- Less time? Spread each week over two weeks. Keep the order, and keep the review days.
- New to code? Do weeks 1 and 2 in a visual pipeline tool, then repeat week 2 in SQL or pandas before moving on.
- Preparing for interviews? Spend the log step practicing out loud: explain each rule in one or two sentences as if to an interviewer.
- Missed a day? Skip ahead rather than doubling up. The review days are there to catch up.
Frequently asked questions
Can I really learn data cleaning in 30 days?
You can build a solid working habit in 30 days: profiling first, applying stated policies, keeping exceptions and reconciling. Judgment on unfamiliar real data keeps improving well after that, which is why the plan ends with a real dataset rather than another exercise.
Should I do the plan in SQL or pandas?
Pick whichever you'll use at work or in interviews as your main tool, and use the other only on review days. The cross-check is valuable because the two tools handle missing values, joins and types differently.
What if I don't have 30 minutes a day?
Do three sessions a week and take ten weeks instead of four. Consistency matters more than speed, and the week-by-week order works at any pace.
Start with day 1 today
Open any small CSV, profile it before you change anything, and write your first line in the rule log. For the broader habits behind this plan, see how to practice data cleaning.
Related reading
Sources
- pandas,
read_csvAPI reference (na_valuesandkeep_default_na). - pandas, Working with missing data.
- DuckDB, CSV import overview (version 1.5 documentation).
- The pandas example was run with pandas 3.0.2.