Sorting & Merging

Real projects usually mean combining data from more than one source. This lesson covers sorting a DataFrame into a useful order, then joining two DataFrames together the way you'd join tables in SQL.

Sorting with .sort_values()

>>> highest score first
import pandas as pd

df = pd.DataFrame({"name": ["Maya", "Sam", "Priya"], "score": [88, 92, 79]})
print(df.sort_values("score", ascending=False))
Output
    name  score
1    Sam     92
0   Maya     88
2  Priya     79

Sort by several columns by passing a list — pandas breaks ties in the first column using the second, and so on: df.sort_values(["region", "score"], ascending=[True, False]).

Merging two DataFrames

pd.merge() joins two DataFrames on a shared column, the same idea as a SQL JOIN covered in the SQL course:

>>> joining orders to customers
orders = pd.DataFrame({"order_id": [1, 2, 3], "customer_id": [101, 102, 101]})
customers = pd.DataFrame({"customer_id": [101, 102], "name": ["Maya", "Sam"]})

merged = pd.merge(orders, customers, on="customer_id")
print(merged)
Output
   order_id  customer_id  name
0         1          101  Maya
1         2          102   Sam
2         3          101  Maya

on="customer_id" tells pandas which column to match rows on. Each order picked up its customer's name by matching customer_id in both tables — order 3 correctly got "Maya" again since it shares customer 101 with order 1.

Watch for: pd.merge() defaults to an inner join — a row that has no match on the other side is silently dropped from the result. If a customer with no orders should still show up (with empty/NaN order columns), you need how="left" or how="outer" explicitly; otherwise rows can vanish without any warning.

Stacking DataFrames with concat

When you have two DataFrames with the same columns — say, sales from January and February — pd.concat() stacks them into one:

>>> stacking
jan = pd.DataFrame({"product": ["Pen"], "quantity": [10]})
feb = pd.DataFrame({"product": ["Pen"], "quantity": [7]})
print(pd.concat([jan, feb], ignore_index=True))
Output
  product  quantity
0     Pen        10
1     Pen         7

ignore_index=True renumbers the result 0, 1, 2… instead of keeping each piece's original index, which would otherwise leave you with duplicate index labels (two rows both labeled 0).