Lesson 9 · Data analytics zero to hero
Pandas Data Wrangling: Reshape & Transform Data | Data Analytics #9
Video nine of the 30-part series: transforming columns with apply and map, splitting text, binning numbers, and filtering with query. We're continuing with…
- CourseData analytics zero to hero
- Lesson9 of 30
- Video11 min
- FormatJupyter notebook · 11 code cells
- Data1 dataset
What you'll learn
Datasets used in this lesson
Save these next to the notebook. In Google Colab, upload them with the 📁 icon on the left first.
- online_retail_sample.csv132.5 KB
📓 Full notebook
Download .ipynbData Analytics Zero to Hero, Video 9: Pandas Data Wrangling#
- Video nine of the 30-part series: transforming columns with apply and map, splitting text, binning numbers, and filtering with query.
- We're continuing with the real, now-cleaned Online Retail extract from video eight.
- Let's jump straight in.
Before You Start#
- Open a new Jupyter Notebook in VS Code and select your Python interpreter as the kernel.
- Place online_retail_sample.csv in the same folder as this notebook.
Re-Cleaning Quickly#
import pandas as pd
df = pd.read_csv('online_retail_sample.csv')
df = df.dropna(subset=['CustomerID']).drop_duplicates()
df['Description'] = df['Description'].fillna('UNKNOWN ITEM').str.strip()
df = df[(df['Quantity'] > 0) & (df['UnitPrice'] > 0)]
print(df.shape)
Part 1: apply and map#
df['TotalPrice'] = df['Quantity'] * df['UnitPrice']
print(df[['Description', 'Quantity', 'UnitPrice', 'TotalPrice']].head(3))
def price_tier(price):
if price >= 10:
return 'Premium'
elif price >= 3:
return 'Standard'
else:
return 'Budget'
df['PriceTier'] = df['UnitPrice'].apply(price_tier)
print(df['PriceTier'].value_counts())
country_region = {'United Kingdom': 'Europe', 'France': 'Europe', 'Germany': 'Europe', 'Norway': 'Europe', 'EIRE': 'Europe'}
df['Region'] = df['Country'].map(country_region).fillna('Other')
print(df['Region'].value_counts())
Part 2: Splitting and Extracting Text#
df['FirstWord'] = df['Description'].str.split().str[0]
print(df[['Description', 'FirstWord']].head(5))
df['DescLength'] = df['Description'].str.len()
print(df['DescLength'].describe())
Part 3: Binning Numbers with cut and qcut#
bins = [0, 5, 20, 50, float('inf')]
labels = ['Small', 'Medium', 'Large', 'Bulk']
df['OrderSize'] = pd.cut(df['Quantity'], bins=bins, labels=labels)
print(df['OrderSize'].value_counts())
df['SpendQuartile'] = pd.qcut(df['TotalPrice'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
print(df['SpendQuartile'].value_counts())
Part 4: rename, assign, and query#
df = df.rename(columns={'InvoiceNo': 'InvoiceNumber', 'UnitPrice': 'Price'})
print(df.columns.tolist())
df = df.assign(PricePerUnit=lambda d: d['Price'].round(2), IsBulk=lambda d: d['Quantity'] >= 20)
print(df[['Price', 'PricePerUnit', 'IsBulk']].head(3))
bulk_premium = df.query("IsBulk == True and PriceTier == 'Premium'")
print(bulk_premium.shape[0])
print(bulk_premium[['Description', 'Quantity', 'Price']].head(3))
Wrap-Up: What You Learned#
- apply for custom row-by-row logic, and map for dictionary-based lookups.
- Splitting and measuring text columns with the str accessor.
- Binning numeric columns into categories with cut, for fixed bins, and qcut, for equal-sized groups.
- Renaming columns with rename, chaining new columns with assign, and filtering readably with query.
- All applied to the same real, cleaned retail data from video eight.
- Video ten goes deep on groupby and aggregation, the tool you'll reach for constantly once your data is wrangled into shape. Subscribe so it lands automatically see you there.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



