A portfolio project demonstrating professional data entry cleanup and standardization on a messy real estate listings dataset — the kind of work done before importing data into a CRM, MLS platform, or database.
Real estate data often arrives from multiple agents in different formats: prices written as "$200K" or "1.2M", property types spelled 15 different ways, states written as full names or abbreviations. This project takes 200 raw listings and applies a documented, repeatable cleaning pipeline.
(Add notebook screenshots here after running the project)
| Before | After |
|---|---|
![]() |
![]() |
Charts generated:
| Missing Values | Property Type Standardization |
|---|---|
![]() |
![]() |
| Problem | Example | Fix Applied |
|---|---|---|
| Duplicate listings | 20 exact copies | drop_duplicates() |
| Missing values | NaN in bedrooms, sqft, price | Median / mode imputation |
| Property type variants | "house", "HOUSE", "SFH", "single family" |
Lookup map -> 5 canonical categories |
| Mixed price formats | "$200,000", "200K", "1.2M" |
Strip symbols, expand K/M, cast to float |
| Inconsistent city names | "los angeles", "L.A.", "LA" |
Lookup map -> canonical name |
| Inconsistent states | "New York", "N.Y.", "ny" |
Lookup map -> 2-letter USPS code |
| Address formatting | "123 MAIN STREET", "123 main st." |
Title Case + abbreviation map |
| Mixed date formats | "01/15/2023", "January 15, 2023" |
pd.to_datetime(format='mixed') |
- Python 3.9+
- Pandas — data loading, transformation, and export
- NumPy — numeric operations and NaN handling
- Matplotlib — before/after visualizations
- openpyxl — writing the
.xlsxoutput
real-estate-data-entry/
├── data/
│ ├── dirty_real_estate.csv <- generated by generate_dirty_data.py
│ ├── clean_real_estate.csv <- output of the cleaning pipeline
│ ├── clean_real_estate.xlsx <- same data as Excel
│ ├── chart_nulls.png <- missing values chart
│ └── chart_property_types.png <- property type standardization chart
├── generate_dirty_data.py <- creates the messy dataset
├── clean_data.py <- standalone cleaning script (commented)
├── build_notebook.py <- generates portfolio.ipynb
├── portfolio.ipynb <- full interactive walkthrough
└── README.md
pip install pandas numpy matplotlib openpyxl notebookpython generate_dirty_data.pypython clean_data.pypython build_notebook.py # generate the notebook file
jupyter notebook portfolio.ipynb
# then: Cell -> Run AllAfter running the full cleaning pipeline:
| Metric | Before | After |
|---|---|---|
| Total rows | 200 | ~175 |
| Null values | 82 | 0 |
| Duplicate listings | 20 | 0 |
| Property type variants | 15+ | 5 canonical |
| Price data type | mixed strings | float64 |
| State format | mixed (full name / abbr / lowercase) | 2-letter USPS code |
| Date data type | mixed strings | datetime64[ns] |
Key actions:
- Removed 20 duplicate listings
- Imputed or dropped 82 null values
- Reduced 15+ property type spellings to 5 clean categories
- Parsed 3 different date formats into a single
datetimecolumn - Standardized all price strings to
float64 - Mapped all state variants to the 2-letter USPS code
Built as part of a data analytics freelance portfolio. Tools: Python - Pandas - NumPy - Matplotlib - openpyxl
Feel free to fork this project and adapt it to your own dataset.



