🔢 Week 2 – NumPy & Pandas · Day 10
Day 10: Pandas Series & DataFrame
⏱ 2 hours📶 Beginner → Intermediate🎯 100% self-study
Day 10 / 60
✅ Today you will learn
- Series: one labelled column
- DataFrame: a table of Series
- Create from dicts, lists of dicts and NumPy
- Add, rename and drop columns
- Column maths and value_counts()
🏢 In the real world
A Zomato analyst opens a table of yesterday’s 1 lakh orders: restaurant, city, amount, delivery time. Every question – average bill per city, slowest restaurants, top cuisines – starts with a pandas DataFrame.
Series and DataFrame
Series
- One column of values
- Has an index (labels)
- Like a NumPy array + labels
- df["city"] returns a Series
DataFrame
- A table: rows × columns
- Each column is a Series
- Columns can have different types
- Like an Excel sheet or SQL table
Series
Python
import pandas as pd
sales = pd.Series([125000, 98000, 64000, 87000], index=["Delhi", "Mumbai", "Pune", "Jaipur"], name="sales")
print(sales)
print(sales["Pune"], sales.iloc[0])
print(sales[sales > 90000])
print("Total:", sales.sum(), "| Best city:", sales.idxmax())Delhi 125000
Mumbai 98000
Pune 64000
Jaipur 87000
Name: sales, dtype: int64
64000 125000
Delhi 125000
Mumbai 98000
Name: sales, dtype: int64
Total: 374000 | Best city: Delhi
Creating DataFrames
Python
import pandas as pd
orders = pd.DataFrame({
"order_id": [101, 102, 103, 104, 105],
"city": ["Pune", "Delhi", "Pune", "Mumbai", "Delhi"],
"category": ["Grocery", "Electronics", "Fashion", "Grocery", "Grocery"],
"amount": [450, 15999, 1299, 780, 320],
})
print(orders) order_id city category amount
0 101 Pune Grocery 450
1 102 Delhi Electronics 15999
2 103 Pune Fashion 1299
3 104 Mumbai Grocery 780
4 105 Delhi Grocery 320
Python
import pandas as pd
import numpy as np
records = [{"name": "Aman", "maths": 78, "science": 82}, {"name": "Priya", "maths": 92, "science": 88},
{"name": "Rahul", "maths": 65}] # missing science -> NaN
print(pd.DataFrame(records))
rng = np.random.default_rng(0)
print(pd.DataFrame(rng.integers(40, 100, size=(3, 4)), columns=["Q1", "Q2", "Q3", "Q4"], index=["Shop A", "Shop B", "Shop C"])) name maths science
0 Aman 78 82.0
1 Priya 92 88.0
2 Rahul 65 NaN
Q1 Q2 Q3 Q4
Shop A 91 78 70 56
Shop B 58 42 44 40
Shop C 50 88 78 94
Looking inside a DataFrame
Python
import pandas as pd
orders = pd.DataFrame({"order_id": [101, 102, 103, 104, 105], "city": ["Pune", "Delhi", "Pune", "Mumbai", "Delhi"],
"category": ["Grocery", "Electronics", "Fashion", "Grocery", "Grocery"], "amount": [450, 15999, 1299, 780, 320]})
print("shape :", orders.shape)
print("columns:", list(orders.columns))
print("index :", orders.index)
print(orders.dtypes)
orders.info()shape : (5, 4)
columns: ['order_id', 'city', 'category', 'amount']
index : RangeIndex(start=0, stop=5, step=1)
order_id int64
city object
category object
amount int64
dtype: object
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 4 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 order_id 5 non-null int64
1 city 5 non-null object
2 category 5 non-null object
3 amount 5 non-null int64
dtypes: int64(2), object(2)
memory usage: 292.0+ bytes
| order_id | city | category | amount | |
|---|---|---|---|---|
| 0 | 101 | Pune | Grocery | 450 |
| 1 | 102 | Delhi | Electronics | 15999 |
| 2 | 103 | Pune | Fashion | 1299 |
Selecting, adding and removing columns
Python
import pandas as pd
orders = pd.DataFrame({"order_id": [101, 102, 103, 104, 105], "city": ["Pune", "Delhi", "Pune", "Mumbai", "Delhi"],
"category": ["Grocery", "Electronics", "Fashion", "Grocery", "Grocery"], "amount": [450, 15999, 1299, 780, 320]})
print(orders["amount"].tolist()) # one column -> Series
print(orders[["city", "amount"]]) # several -> DataFrame
orders["gst"] = orders["amount"] * 0.18 # new column, vectorised
orders["is_big"] = orders["amount"] > 1000
orders = orders.rename(columns={"amount": "amount_rs"})
orders = orders.drop(columns=["gst"])
print(orders)[450, 15999, 1299, 780, 320]
city amount
0 Pune 450
1 Delhi 15999
2 Pune 1299
3 Mumbai 780
4 Delhi 320
order_id city category amount_rs is_big
0 101 Pune Grocery 450 False
1 102 Delhi Electronics 15999 True
2 103 Pune Fashion 1299 True
3 104 Mumbai Grocery 780 False
4 105 Delhi Grocery 320 False
Column maths and quick stats
Python
import pandas as pd
df = pd.DataFrame({"product": ["Tea", "Atta", "Earbuds", "Kurta"], "qty": [2, 1, 1, 3],
"price": [520, 459, 1499, 899], "discount": [0, 0.05, 0.1, 0.2]})
df["revenue"] = df["qty"] * df["price"] * (1 - df["discount"])
print(df)
print("Total revenue:", df["revenue"].sum().round(2), "| mean price:", df["price"].mean())
print(df[["price", "revenue"]].describe().round(1)) product qty price discount revenue
0 Tea 2 520 0.00 1040.00
1 Atta 1 459 0.05 436.05
2 Earbuds 1 1499 0.10 1349.10
3 Kurta 3 899 0.20 2157.60
Total revenue: 4982.75 | mean price: 844.25
price revenue
count 4.0 4.0
mean 844.2 1245.7
std 477.9 716.5
min 459.0 436.0
25% 504.8 889.0
50% 709.5 1194.6
75% 1049.0 1551.2
max 1499.0 2157.6
Python
import pandas as pd
cities = pd.Series(["Pune", "Delhi", "Pune", "Mumbai", "Delhi", "Pune", "Agra"])
print(cities.value_counts())
print(cities.value_counts(normalize=True).round(2))
print("Unique:", cities.nunique(), list(cities.unique()))Pune 3
Delhi 2
Mumbai 1
Agra 1
Name: count, dtype: int64
Pune 0.43
Delhi 0.29
Mumbai 0.14
Agra 0.14
Name: proportion, dtype: float64
Unique: 4 ['Pune', 'Delhi', 'Mumbai', 'Agra']
Real example: the course sales data
Python
import pandas as pd
sales = pd.read_csv("sales_data.csv")
sales["revenue"] = sales["quantity"] * sales["unit_price"] * (1 - sales["discount"])
print(sales.shape)
print(sales[["order_id", "city", "category", "revenue"]].head())
print("\nOrders per payment mode:")
print(sales["payment_mode"].value_counts())
print("\nAverage order value: ₹", round(sales["revenue"].mean(), 2))(2000, 14)
order_id city category revenue
0 BK100359 Delhi Fashion 2440.0
1 BK100422 Mumbai Fashion 2094.3
2 BK100744 Mumbai Grocery 2625.0
3 BK100830 Mumbai Books & Stationery 138.6
4 BK100947 Bengaluru Fashion 463.5
Orders per payment mode:
payment_mode
UPI 961
Card 485
Cash on Delivery 391
Net Banking 163
Name: count, dtype: int64
Average order value: ₹ 3439.89
🏅 Job skills unlocked today
✔ Create Series and DataFrames✔ Inspect shape, dtypes and info()✔ Add and transform columns✔ Count categories with value_counts()
Practice tasks
🏋️ Practice – do it yourself
Task 1: Create a DataFrame of 5 employees with name, department and salary. Add a column
bonus = 10% of salary.Show solution
Python
import pandas as pd
emp = pd.DataFrame({"name": ["Aarav", "Diya", "Kabir", "Ananya", "Yash"], "dept": ["Sales", "IT", "IT", "HR", "Sales"],
"salary": [52000, 98000, 87000, 45000, 61000]})
emp["bonus"] = emp["salary"] * 0.10
print(emp) name dept salary bonus
0 Aarav Sales 52000 5200.0
1 Diya IT 98000 9800.0
2 Kabir IT 87000 8700.0
3 Ananya HR 45000 4500.0
4 Yash Sales 61000 6100.0
Task 2: Using
sales_data.csv, how many orders came from each region?Show solution
Python
import pandas as pd
print(pd.read_csv("sales_data.csv")["region"].value_counts())region
South 654
West 519
North 508
East 319
Name: count, dtype: int64
Task 3: From
students_performance.csv print the mean of maths, science and english together.Show solution
Python
import pandas as pd
st = pd.read_csv("students_performance.csv")
print(st[["maths", "science", "english"]].mean().round(2))maths 64.90
science 67.18
english 66.77
dtype: float64
Quick quiz
🧠 Quick Quiz – test yourself
1. df["city"] returns a…
One column is a Series; df[["city"]] (double brackets) is a DataFrame.
2. df.shape returns…
Like NumPy: (rows, columns).
3. A missing value in pandas shows as…
NaN = Not a Number.
4. Which shows column types and non-null counts?
info() is the first thing to run on new data.
5. value_counts(normalize=True) shows…
Each count divided by the total – shares that add to 1.
Interview corner
💼 Interview Corner
What is the difference between a pandas Series and a DataFrame?
A Series is one-dimensional – a column of values with an index. A DataFrame is two-dimensional – a collection of Series that share the same index, one per column, possibly of different types.
Why is vectorised column maths preferred over looping rows?
It is much faster (runs in NumPy/C), shorter, less buggy and easier to read. Loops with iterrows are a last resort.
Summary
- Series = one labelled column; DataFrame = table of Series.
- Build from dicts, lists of dicts, NumPy or CSV.
- shape, dtypes, info(), describe() give a quick overview.
- New columns come from vectorised maths on old columns.
➡️ Next
Day 11: read CSV, Excel and JSON files the professional way and explore any new dataset in five minutes.
Frequently Asked Questions
Why import pandas as pd?
It is a universal convention – every tutorial, Stack Overflow answer and company codebase uses pd.
Does drop() change the original DataFrame?
No, it returns a new one. Assign it back (df = df.drop(...)) – inplace=True also works but is being discouraged.
