By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
You’re working on a customer analytics dashboard for an e-commerce company. Your boss hands you two CSV files: - customers.csv (customer IDs, names, emails, signup dates) - orders.csv (order IDs, customer IDs, order dates, amounts)
customers.csv
orders.csv
Your task: Generate a report showing total spending per customer, segmented by signup month.
Problem: The data is split across two files. If you don’t know how to merge, join, or concatenate DataFrames, you’ll waste hours manually matching rows in Excel—or worse, write buggy loops that crash when data is missing.
Why this matters in production:- Data is never clean or single-sourced. You’ll always work with multiple datasets (SQL tables, APIs, CSVs, Parquet files).- Performance matters. A bad merge can turn a 1-second operation into a 10-minute bottleneck.- Debugging is painful. If you don’t understand how='left' vs. how='inner', you’ll silently drop rows or duplicate data—leading to wrong business decisions.
how='left'
how='inner'
Real-world scenario:You’re building a fraud detection model. You have: - Transaction data (from a database) - User profiles (from a CRM API) - Historical fraud labels (from a legacy system)
To train the model, you must combine these datasets correctly. A single merge mistake could mean false positives (blocking good customers) or false negatives (letting fraud slip through).
pd.concat()
NaN
pd.merge()
how=
inner
df.join()
merge
how='right'
left
how='outer'
on=
left_on=
right_on=
suffixes=
_left
_right
validate=
validate='one_to_one'
pandas
pip install pandas
customer_id
name
email
signup_date
order_id
order_date
amount
import pandas as pd customers = pd.read_csv("customers.csv") orders = pd.read_csv("orders.csv") print(customers.head()) print(orders.head())
Expected output:
customer_id name email signup_date 0 1 Alice Smith [email protected] 2023-01-15 1 2 Bob Jones [email protected] 2023-02-20 order_id customer_id order_date amount 0 1 1 2023-03-10 99.99 1 2 1 2023-04-05 49.99
merged = pd.merge(customers, orders, on="customer_id") print(merged.head())
customer_id name email signup_date order_id order_date amount 0 1 Alice Smith [email protected] 2023-01-15 1 2023-03-10 99.99 1 1 Alice Smith [email protected] 2023-01-15 2 2023-04-05 49.99
⚠️ Problem: If a customer has no orders, they’re dropped silently.
merged_left = pd.merge(customers, orders, on="customer_id", how="left") print(merged_left[merged_left["order_id"].isna()])
customer_id name email signup_date order_id order_date amount 3 3 Charlie Lee [email protected] 2023-05-10 NaN NaN NaN
✅ Success: We see Charlie Lee has no orders.
spending = merged_left.groupby("customer_id").agg( total_spent=("amount", "sum"), order_count=("order_id", "count"), first_order_date=("order_date", "min") ).reset_index() print(spending)
customer_id total_spent order_count first_order_date 0 1 149.98 2 2023-03-10 1 2 0.00 0 NaN 2 3 0.00 0 NaN
final_report = pd.merge(customers, spending, on="customer_id", how="left") print(final_report)
customer_id name email signup_date total_spent order_count first_order_date 0 1 Alice Smith [email protected] 2023-01-15 149.98 2 2023-03-10 1 2 Bob Jones [email protected] 2023-02-20 0.00 0 NaN 2 3 Charlie Lee [email protected] 2023-05-10 0.00 0 NaN
# Simulate two monthly sales files jan_sales = pd.DataFrame({ "order_id": [101, 102], "customer_id": [1, 2], "amount": [50.00, 75.00] }) feb_sales = pd.DataFrame({ "order_id": [103], "customer_id": [1], "amount": [30.00] }) # Stack vertically all_sales = pd.concat([jan_sales, feb_sales], ignore_index=True) print(all_sales)
order_id customer_id amount 0 101 1 50.00 1 102 2 75.00 2 103 1 30.00
left_on
right_on
outer
len(df)
suffixes=('_left', '_right')
python print(f"Left DF rows: {len(left_df)}, Right DF rows: {len(right_df)}, Merged rows: {len(merged_df)}")
customers_df
orders_df
python # Left join to preserve all customers, even those with no orders merged = pd.merge(customers_df, orders_df, on="customer_id", how="left")
pd.DataFrame.merge()
df.merge()
0
fillna()
python merged["amount"].fillna(0, inplace=True)
df.columns
pd.concat([df1, df2], ignore_index=True, sort=False)
❌ how='inner' (drops unmatched rows)
"You have two DataFrames with different column names for the key. How do you merge them?"
pd.merge(df1, df2, left_on="cust_id", right_on="customer_id")
❌ pd.merge(df1, df2, on="cust_id") (fails if column names differ)
pd.merge(df1, df2, on="cust_id")
"What’s the difference between concat and merge?"
concat
merge → SQL-style joins on keys.
"How do you detect duplicate keys before merging?"
df.duplicated().sum()
Task:You have two DataFrames:
employees = pd.DataFrame({ "emp_id": [1, 2, 3], "name": ["Alice", "Bob", "Charlie"], "dept_id": [101, 102, 101] }) departments = pd.DataFrame({ "dept_id": [101, 102, 103], "dept_name": ["Engineering", "Marketing", "HR"] })
Goal: Merge them to show employee names with their department names. Include employees even if their department doesn’t exist in departments.
departments
Solution:
result = pd.merge(employees, departments, on="dept_id", how="left") print(result)
Why it works:- how='left' preserves all employees.- on="dept_id" matches the key column.- Missing departments show as NaN.
on="dept_id"
pd.merge(df1, df2, on="key")
pd.merge(df1, df2, on="key", how="left")
pd.merge(df1, df2, on="key", how="outer")
pd.merge(df1, df2, left_on="key1", right_on="key2")
pd.merge(df1, df2, on="key", suffixes=('_left', '_right'))
pd.merge(df1, df2, on="key", validate="one_to_one")
pd.concat([df1, df2], ignore_index=True)
pd.concat([df1, df2], axis=1)
join
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.