Create clean as a separate copy of df.
The editable setup on the right creates df. Run executes the setup and your work from top to bottom.
Your requirements
- Remove confirmed extra identical rows, keeping the first occurrence.
- Strip and lowercase drink; strip and title-case size.
- Convert price to numeric and date to datetime with year-month-day format, making invalid values missing.
- Fill missing tip with the median after deduplication.
- Sort by order ascending and reset to consecutive row labels without adding an index column.
- Keep all other values and retain rows with unknown price.
- Display clean.
Your inputs
| order | drink | size | price | tip | date |
|---|---|---|---|---|---|
| 101 | " latte " | LARGE | 6.20 | 1 | 2026-06-01 |
| 102 | TEA | small | 3.10 | 0.5 | 2026-06-02 |
| 103 | " mocha " | LARGE | oops | None | not a date |
| 104 | Latte | Small | None | 0.8 | 2026-06-04 |
| 104 | Latte | Small | None | 0.8 | 2026-06-04 |
| 105 | "tea " | SMALL | 4.20 | 0.6 | 2026-06-05 |
| 106 | ESPRESSO | small | 2.50 | 0.2 | 2026-06-06 |
| 107 | " mocha" | large | 6.80 | 1.5 | 2026-06-07 |
Remember the idea
A cleaning policy specifies which records and values may change, and why.
A small example
Parse a numeric field before deciding whether it meets a report’s required-field policy.
| Code or choice | Meaning |
|---|---|
Copy and deduplicate | Keep the source; remove only confirmed accidental copies. |
Normalize and parse | Clean labels, convert types and keep invalid values visible as gaps. |
Prepare the handoff | Apply the stated fill and eligibility rules, then select, sort and reset as requested. |
Hint
Copy first. Remove confirmed duplicate records before calculating the imputation median; preserve unknown prices.
Reveal solution
One way to do it. Keep any supplied setup in the editor and use this in the Your work section.
clean = df.copy()
clean = clean.drop_duplicates()
clean["drink"] = clean["drink"].str.strip().str.lower()
clean["size"] = clean["size"].str.strip().str.title()
clean["price"] = pd.to_numeric(clean["price"], errors="coerce")
clean["date"] = pd.to_datetime(clean["date"], format="%Y-%m-%d", errors="coerce")
clean["tip"] = clean["tip"].fillna(clean["tip"].median())
clean = clean.sort_values("order").reset_index(drop=True)
clean