Lesson 29: Introduction to Pandas — Data Analysis with Python
Lesson 29: Introduction to Pandas — Data Analysis with Python
Lesson Introduction
Welcome to one of the most powerful lessons in this series! In this lesson, you will learn Pandas — a Python library that lets you work with data the way a scientist, analyst, or engineer does every day.
Imagine you have a huge spreadsheet of student grades, weather readings, sales figures, or health records. Instead of clicking through menus in Excel, Pandas lets you write a few lines of Python code to load, explore, clean, filter, and summarise that data instantly.
By the end of this lesson, you will be able to:
- Understand what Pandas is and why it exists
- Install and import Pandas into your Python programs
- Create and work with Series (a single column of data)
- Create and work with DataFrames (a full table of data)
- Load real data from CSV files and JSON files
- Access specific rows and columns using labels and index numbers
- Build a simple real-world data mini-project from scratch
No prior data analysis experience is required. We will start from zero and build up together, step by step.
Prerequisite Concepts
Before diving in, let’s quickly review two Python concepts this lesson depends on. If you already know these, feel free to skim.
Python Lists
A list is a collection of values stored in order. Think of it like a numbered shopping list.
fruits = ["apple", "banana", "cherry"]
print(fruits[0]) # Access first item by its index number
Expected Output:
apple
Each item has an index — a number starting from 0 that tells Python where in the list that item lives.
Python Dictionaries
A dictionary stores data as key-value pairs — like a word and its definition in a real dictionary.
person = {"name": "Amara", "age": 22, "city": "Lagos"}
print(person["name"])
Expected Output:
Amara
You use the key (the word on the left) to look up its value (the data on the right). Pandas uses dictionaries heavily when creating tables of data.
Python import Statement
When you want to use an external tool or library in Python, you bring it in with import.
import math
print(math.sqrt(25))
Expected Output:
5.0
You will use import to bring Pandas into every program you write in this lesson.
Section 1: What Is Pandas?
The Big Picture — Why Does Pandas Exist?
Imagine you work for a hospital, a bank, or a university. Every day, thousands of records are collected: patient readings, transactions, exam scores. You need to answer questions like:
- What is the average score across all students?
- Which patient has the highest blood pressure?
- On which day did the store earn the most money?
Before Pandas, answering these questions required writing long, complex Python code just to organise the data, let alone analyse it.
Pandas was created in 2008 by Wes McKinney to solve exactly this problem. The name stands for “Panel Data” and “Python Data Analysis” — two hints at what it does.
What Pandas Actually Does
Pandas is a Python library. A library is simply a collection of pre-written code that someone else (or a team) built and packaged for you to use freely. When you use Pandas, you are borrowing thousands of hours of work to do powerful things in just a few lines.
With Pandas you can:
- Analyse big datasets — find averages, maximums, minimums
- Clean messy data — fix errors, remove blanks, correct wrong values
- Explore data — look at its shape, types, and patterns
- Manipulate data — sort, filter, combine, and reshape tables
- Load data from external files — CSV, JSON, Excel, and more
💡 Real-world analogy: Think of Pandas as a supercharged spreadsheet that you control with Python code. Excel can handle perhaps a few hundred thousand rows before slowing down. Pandas can handle millions of rows efficiently.
Where Is Pandas Stored?
Pandas is an open-source project. Its code lives at https://github.com/pandas-dev/pandas where developers from all over the world contribute improvements. GitHub is a platform where many people can work on the same codebase at once — think of it as Google Docs for code.
What Fields Use Pandas?
Pandas is used in virtually every field that works with data:
- Data Science and Machine Learning — preparing datasets for AI models
- Finance and Banking — analysing stock prices, transactions, risk
- Healthcare — processing patient records and clinical trial data
- Engineering — analysing sensor readings and measurements
- Education — processing exam results and student performance
- Business — sales analysis, customer behaviour, inventory tracking
Section 2: Getting Started — Installing and Importing Pandas
Step 1: Install Pandas
Before you can use Pandas, you must install it. Pandas is not built into Python by default, so you need to add it using PIP — Python’s package manager.
Open your terminal (also called the command prompt or shell) and type:
pip install pandas
What this command does:
pip— this is Python’s install helper toolinstall— tells pip to download and install a packagepandas— the name of the package to install
If the installation is successful, you will see output ending with something like:
Successfully installed pandas-2.x.x
💡 Tip: If you are using an environment like Anaconda, Spyder, or Google Colab, Pandas is usually already pre-installed. You can skip the installation step and go straight to importing.
Step 2: Import Pandas
Once Pandas is installed, you bring it into your Python script using the import keyword. You do this at the very top of every file where you want to use Pandas.
The full import (less common):
import pandas
print(pandas.__version__)
Expected Output:
2.x.x
The standard import with an alias (used everywhere):
import pandas as pd
print(pd.__version__)
Expected Output:
2.x.x
Understanding the as pd Alias
An alias is a shorter nickname for something. Instead of typing pandas every time you want to use the library, you give it the short name pd. This is a universal convention — every Pandas programmer in the world uses import pandas as pd. You will see pd used in all examples from this point forward.
Think of it like this: instead of saying “please pass me the television remote control”, you just say “remote”. Same object, shorter name.
Verifying the version:
import pandas as pd
print(pd.__version__)
The __version__ attribute (the double underscores mean it is a special built-in attribute) stores the version string of the installed library. Checking this is a simple way to confirm Pandas loaded correctly.
Section 3: Pandas Series — A Single Column of Data
What Is a Series?
A Pandas Series is a one-dimensional array — meaning it is a single column of data. You can think of it as a list, but smarter.
💡 Analogy: If a DataFrame is a full spreadsheet, a Series is one single column of that spreadsheet. For example, the “Temperature” column in a weather table, or the “Score” column in a student grade table.
A Series can hold any type of data: numbers, text, dates, True/False values.
Creating a Simple Series from a List
import pandas as pd
a = [1, 7, 2]
myvar = pd.Series(a)
print(myvar)
Expected Output:
0 1
1 7
2 2
dtype: int64
Breaking down this output line by line:
- The left column (
0,1,2) shows the index — the label for each position, automatically assigned starting from0 - The right column (
1,7,2) shows the values — the actual data you provided dtype: int64— this tells you the data type.int64means 64-bit integer (whole numbers). Pandas automatically detects what type your data is.
🤔 Thinking prompt: What happens if you change
a = [1, 7, 2]toa = [10, 20, 30]? Try it — does the index change? Why or why not?
Accessing Values by Index
Once a Series is created, you can retrieve any value using its index number inside square brackets [].
import pandas as pd
a = [1, 7, 2]
myvar = pd.Series(a)
print(myvar[0]) # First value (index 0)
print(myvar[1]) # Second value (index 1)
print(myvar[2]) # Third value (index 2)
Expected Output:
1
7
2
The index always starts at 0, not 1. This is called zero-based indexing and is standard in Python.
Creating a Series with Custom Labels
By default, Pandas numbers the index 0, 1, 2, and so on. But you can give your own meaningful names to the index positions using the index argument.
import pandas as pd
a = [1, 7, 2]
myvar = pd.Series(a, index = ["x", "y", "z"])
print(myvar)
Expected Output:
x 1
y 7
z 2
dtype: int64
Now the index labels are "x", "y", and "z" instead of numbers. This makes it easier to understand what each value represents.
Accessing by custom label:
print(myvar["y"])
Expected Output:
7
You can use either the label ("y") or the numeric position ([1]) to access the value — they both work!
Creating a Series from a Dictionary
A very common way to create a Series is from a Python dictionary, because dictionaries already have the key-value structure that maps perfectly to index-value pairs.
import pandas as pd
calories = {"day1": 420, "day2": 380, "day3": 390}
myvar = pd.Series(calories)
print(myvar)
Expected Output:
day1 420
day2 380
day3 390
dtype: int64
What happened here?
- The dictionary keys (
"day1","day2","day3") automatically became the index labels - The dictionary values (
420,380,390) became the Series values
This is extremely useful when you have labelled data — like calorie counts per day, or temperatures per city.
Selecting Only Some Items from a Dictionary
Sometimes you have a dictionary with many entries but only want to include some of them in your Series. Use the index argument to specify which keys to include:
import pandas as pd
calories = {"day1": 420, "day2": 380, "day3": 390}
myvar = pd.Series(calories, index = ["day1", "day2"])
print(myvar)
Expected Output:
day1 420
day2 380
dtype: int64
Only day1 and day2 were included. day3 was ignored because it was not listed in the index argument.
🤔 Thinking prompt: What do you think would happen if you listed a key in
indexthat does NOT exist in the dictionary? Tryindex = ["day1", "day5"]. What does Pandas return forday5?
Section 4: Pandas DataFrames — The Full Data Table
What Is a DataFrame?
If a Series is a single column, a DataFrame is the entire table — rows AND columns.
A Pandas DataFrame is a two-dimensional (2D) data structure, similar to a spreadsheet or a SQL table. It has:
- Rows — each row represents one record (e.g., one student, one day’s workout, one product)
- Columns — each column represents one attribute or measurement (e.g., name, score, price)
- Index — labels for each row (automatically numbered 0, 1, 2… unless you name them)
💡 Analogy: Think of a DataFrame as an Excel sheet. Each column is a Series. Multiple Series stacked side by side form a DataFrame.
Creating a Simple DataFrame
You create a DataFrame by passing a Python dictionary to pd.DataFrame(). Each key in the dictionary becomes a column name, and each list of values becomes that column’s data.
import pandas as pd
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data)
print(df)
Expected Output:
calories duration
0 420 50
1 380 40
2 390 45
Explaining every part of this output:
- The top row (
calories duration) shows the column headers — one for each key in the dictionary - The leftmost column (
0,1,2) shows the row index — automatically assigned, starting at0 - Each row of numbers represents one record. Row
0says “this workout burned 420 calories and lasted 50 minutes”
By convention, the variable holding a DataFrame is often called df. This is just a short, recognisable name — like how we use x for unknowns in maths.
Locating a Specific Row Using .loc
Once you have a DataFrame, you often need to look at one specific row. Pandas provides the .loc attribute (short for “locate”) for this purpose.
Access a single row by index number:
import pandas as pd
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data)
print(df.loc[0])
Expected Output:
calories 420
duration 50
Name: 0, dtype: int64
Notice: when you locate a single row, the result is displayed vertically and is actually a Pandas Series! The column names become the index labels, and the values in that row become the values.
Access multiple rows by passing a list of indexes:
print(df.loc[[0, 1]])
Expected Output:
calories duration
0 420 50
1 380 40
When you pass a list [0, 1] to .loc, the result is a DataFrame (a table with multiple rows). Notice the double square brackets — [[0, 1]] not [0, 1].
💡 Key rule:
.loc[0]→ returns a Series (one row)..loc[[0, 1]]→ returns a DataFrame (multiple rows).
Creating a DataFrame with Named Row Indexes
By default, row indexes are numbers (0, 1, 2…). You can give rows meaningful names using the index parameter:
import pandas as pd
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
print(df)
Expected Output:
calories duration
day1 420 50
day2 380 40
day3 390 45
Now each row is labelled with a meaningful name. This is very useful for time-series data (data measured over days, months, years).
Accessing a named row:
print(df.loc["day2"])
Expected Output:
calories 380
duration 40
Name: day2, dtype: int64
You used the string "day2" as the row label, and .loc found it instantly.
🤔 Thinking prompt: Can you add a third column called
"heartrate"with values[120, 110, 115]to the dictionary and recreate the DataFrame? What does the output look like?
Loading Data from Files into a DataFrame
In real work, you will rarely type all your data manually. You will load it from external files. The most common types are CSV and JSON.
import pandas as pd
df = pd.read_csv('data.csv')
print(df)
This loads an entire file of data into a DataFrame with one line of code. You will learn the full details of this in the next sections.
Section 5: Reading CSV Files
What Is a CSV File?
A CSV file (Comma-Separated Values) is a plain text file that stores tabular data. Each row in the file is one record, and the values within each row are separated by commas.
Here is what a simple CSV file looks like when you open it in a text editor:
Duration,Pulse,Maxpulse,Calories
60,110,130,409
60,117,145,479
60,103,135,340
45,109,175,282
45,117,148,406
60,102,127,300
The first line is the header row — it contains the column names. Every line after that is one row of data. CSV files are extremely common because they are simple, human-readable, and supported by almost every tool including Excel, Python, and databases.
💡 Real-world use: CSV files are how many banks export transaction histories, how hospitals share patient records between systems, and how weather services distribute climate data.
Reading a CSV File with Pandas
Pandas has a built-in function called pd.read_csv() that reads a CSV file and converts it into a DataFrame automatically.
import pandas as pd
df = pd.read_csv('data.csv')
print(df.to_string())
What each line does:
import pandas as pd— loads the Pandas library with the short namepdpd.read_csv('data.csv')— reads the file nameddata.csvand builds a DataFrame from it, stored indfdf.to_string()— converts the entire DataFrame to a string for printing, so you see every row
Expected Output (abbreviated):
Duration Pulse Maxpulse Calories
0 60 110 130 409.1
1 60 117 145 479.0
2 60 103 135 340.0
3 45 109 175 282.4
4 45 117 148 406.0
...
💡 Tip: Without
.to_string(), if the DataFrame has many rows, Pandas only prints the first 5 and the last 5 rows by default, with...in between. Usingto_string()forces it to display everything.
Printing Without .to_string()
If you just do print(df) on a large dataset:
import pandas as pd
df = pd.read_csv('data.csv')
print(df)
Expected Output (for a large file):
Duration Pulse Maxpulse Calories
0 60 110 130 409.1
1 60 117 145 479.0
2 60 103 135 340.0
3 45 109 175 282.4
4 45 117 148 406.0
.. ... ... ... ...
164 60 105 140 290.8
165 60 110 145 300.0
...
[169 rows x 5 columns]
Pandas truncates the output to be readable. It shows 5 rows from the top and 5 from the bottom, then shows you the total number of rows and columns at the bottom.
Checking and Changing the Maximum Display Rows
Pandas has a setting that controls how many rows are shown when you print a DataFrame. You can check it like this:
import pandas as pd
print(pd.options.display.max_rows)
Expected Output:
60
This means: if your DataFrame has more than 60 rows, Pandas will only show the first and last 5 when you print(df).
Changing the maximum rows:
import pandas as pd
pd.options.display.max_rows = 9999
df = pd.read_csv('data.csv')
print(df)
By setting max_rows to 9999, you are telling Pandas to show up to 9,999 rows without truncating. This is useful when you want to inspect the full dataset.
Why does this setting exist? Because some real-world datasets have millions of rows. Printing all of them to the terminal would be both slow and useless. Pandas defaults to showing a manageable summary.
Section 6: Reading JSON Files
What Is JSON?
JSON stands for JavaScript Object Notation. Despite the name mentioning JavaScript, JSON is a universal data format used everywhere — web APIs, databases, configuration files, and data science pipelines.
JSON uses a structure that looks very similar to a Python dictionary:
{
"Duration": {"0": 60, "1": 60, "2": 60},
"Pulse": {"0": 110, "1": 117, "2": 103},
"Calories": {"0": 409, "1": 479, "2": 340}
}
The outer keys ("Duration", "Pulse", "Calories") are column names. The inner keys ("0", "1", "2") are row indexes. The inner values are the data.
💡 Key insight: JSON = Python Dictionary (in terms of structure). This is why Pandas can load both with ease.
Reading a JSON File
Just like CSV, Pandas has a dedicated function: pd.read_json().
import pandas as pd
df = pd.read_json('data.json')
print(df.to_string())
Expected Output:
Duration Pulse Maxpulse Calories
0 60 110 130 409.1
1 60 117 145 479.0
2 60 103 135 340.0
...
The result is identical to reading the CSV — a proper DataFrame with column headers and row indexes. Pandas handles the conversion for you.
Loading a Python Dictionary Directly as JSON
Since JSON and Python dictionaries share the same structure, you can also pass a Python dictionary directly to pd.DataFrame() to simulate reading JSON data without needing a file:
import pandas as pd
data = {
"Duration": {
"0": 60,
"1": 60,
"2": 60,
"3": 45,
"4": 45,
"5": 60
},
"Pulse": {
"0": 110,
"1": 117,
"2": 103,
"3": 109,
"4": 117,
"5": 102
},
"Maxpulse": {
"0": 130,
"1": 145,
"2": 135,
"3": 175,
"4": 148,
"5": 127
},
"Calories": {
"0": 409,
"1": 479,
"2": 340,
"3": 282,
"4": 406,
"5": 300
}
}
df = pd.DataFrame(data)
print(df)
Expected Output:
Duration Pulse Maxpulse Calories
0 60 110 130 409
1 60 117 145 479
2 60 103 135 340
3 45 109 175 282
4 45 117 148 406
5 60 102 127 300
What happened here, step by step:
- We defined a nested dictionary where outer keys are column names and inner keys are row index labels
pd.DataFrame(data)read that dictionary and converted it into a DataFrame- Pandas automatically aligned all the values by their matching index keys
This approach is useful when your data comes from an API (a web service that returns JSON) and you want to quickly turn it into a DataFrame for analysis.
CSV vs JSON — A Quick Comparison
| Feature | CSV | JSON |
|---|---|---|
| Format | Plain text, comma-separated | Structured key-value pairs |
| Readability | Very simple, human-readable | More structured, slightly more complex |
| Use case | Flat tables, spreadsheet exports | Web APIs, nested or hierarchical data |
| Pandas function | pd.read_csv() |
pd.read_json() |
Both formats are extremely common. A data analyst needs to be comfortable with both.
Section 7: Guided Practice Exercises
Exercise 1: Creating Your First Series
Objective: Create and explore a Pandas Series using a list.
Scenario: You are tracking the daily temperatures (in °C) in Lagos for 5 days.
Steps:
- Create a list:
[32, 34, 30, 35, 31] - Create a Pandas Series from that list
- Print the full Series
- Print only the temperature for day 3 (index
2) - Create the same Series again but with custom labels:
["Mon", "Tue", "Wed", "Thu", "Fri"] - Access Wednesday’s temperature using its label
Solution:
import pandas as pd
# Step 1-3: Create and print
temperatures = [32, 34, 30, 35, 31]
temp_series = pd.Series(temperatures)
print(temp_series)
Expected Output:
0 32
1 34
2 30
3 35
4 31
dtype: int64
# Step 4: Access by index
print(temp_series[2])
Expected Output:
30
# Step 5-6: Custom labels
temp_series_labelled = pd.Series(temperatures, index=["Mon", "Tue", "Wed", "Thu", "Fri"])
print(temp_series_labelled)
print(temp_series_labelled["Wed"])
Expected Output:
Mon 32
Tue 34
Wed 30
Thu 35
Fri 31
dtype: int64
30
Self-check questions:
- What is the difference between
temp_series[2]andtemp_series_labelled["Wed"]? - Why do both return
30? - What happens if you try
temp_series["Wed"]?
Exercise 2: Building a Student Grade DataFrame
Objective: Create a DataFrame from a dictionary and use .loc to access specific rows.
Scenario: You are an assistant at a university building a grade sheet for five students.
Steps:
- Create a dictionary with keys
"student","maths","english","science" - Fill each key with a list of five values
- Create a DataFrame from the dictionary
- Print the full DataFrame
- Use
.locto print the data for student at index0 - Use
.locto print data for students at indexes1and3
Solution:
import pandas as pd
# Step 1-4
data = {
"student": ["Amara", "Bola", "Chidi", "Dami", "Emeka"],
"maths": [85, 72, 90, 65, 78],
"english": [88, 80, 76, 91, 70],
"science": [79, 85, 92, 60, 83]
}
df = pd.DataFrame(data)
print(df)
Expected Output:
student maths english science
0 Amara 85 88 79
1 Bola 72 80 85
2 Chidi 90 76 92
3 Dami 65 91 60
4 Emeka 78 70 83
# Step 5: Single row
print(df.loc[0])
Expected Output:
student Amara
maths 85
english 88
science 79
Name: 0, dtype: object
# Step 6: Multiple rows
print(df.loc[[1, 3]])
Expected Output:
student maths english science
1 Bola 72 80 85
3 Dami 65 91 60
Optional What-If Challenge: Add an index parameter to give each student their student ID as the row label (e.g., "S001", "S002", …). Then use .loc["S003"] to access Chidi’s grades.
Exercise 3: Reading and Exploring CSV Data
Objective: Practice loading a CSV file and controlling how it displays.
Scenario: You download a dataset of workout sessions. Create a small sample CSV in your mind (or actually create the file) and load it.
Steps:
- Create a file called
workouts.csvwith the following content (save it in the same folder as your Python file):
day,duration_minutes,calories_burned,heartrate
Monday,45,350,130
Tuesday,60,450,145
Wednesday,30,220,115
Thursday,50,400,138
Friday,40,310,125
Saturday,75,600,155
Sunday,20,160,105
- Load it using
pd.read_csv() - Print it using
to_string()to see everything - Print it without
to_string()to see the default behaviour - Check the current
max_rowssetting
Solution:
import pandas as pd
# Step 2-3
df = pd.read_csv('workouts.csv')
print(df.to_string())
Expected Output:
day duration_minutes calories_burned heartrate
0 Monday 45 350 130
1 Tuesday 60 450 145
2 Wednesday 30 220 115
3 Thursday 50 400 138
4 Friday 40 310 125
5 Saturday 75 600 155
6 Sunday 20 160 105
# Step 5
print(pd.options.display.max_rows)
Expected Output:
60
Exercise 4: Loading JSON Data from a Dictionary
Objective: Create a DataFrame from a nested dictionary (simulating JSON data).
Scenario: You receive a JSON-style data payload from a weather API with temperature data for three cities over three days.
import pandas as pd
weather_data = {
"Lagos": {"Mon": 32, "Tue": 34, "Wed": 30},
"Abuja": {"Mon": 28, "Tue": 29, "Wed": 27},
"Kano": {"Mon": 35, "Tue": 37, "Wed": 33}
}
df = pd.DataFrame(weather_data)
print(df)
Expected Output:
Lagos Abuja Kano
Mon 32 28 35
Tue 34 29 37
Wed 30 27 33
Notice: here the outer keys became the column names (cities), and the inner keys became the row index labels (days). This is the natural structure when the dictionary is organised by column.
Self-check questions:
- How would you access the temperature in Abuja on Tuesday?
- What happens if you use
df.loc["Tue"]?
Section 8: Mini Project — Weekly Fitness Tracker
This mini-project pulls together everything you have learned: creating Series, building DataFrames, naming indexes, and loading data.
Project Goal: Build a weekly fitness tracker that stores, displays, and accesses a person’s daily workout data using Pandas.
Stage 1: Setup — Create the Data
Scenario: Adaeze is tracking her fitness for one week. She records: how many minutes she exercised, how many calories she burned, and her average heart rate.
import pandas as pd
# Stage 1: Create the workout data as a dictionary
workout_data = {
"duration_min": [45, 60, 30, 55, 40, 75, 20],
"calories": [350, 450, 220, 420, 310, 600, 160],
"heartrate": [130, 145, 115, 140, 125, 155, 105]
}
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
df = pd.DataFrame(workout_data, index=days)
print("=== Adaeze's Weekly Fitness Log ===")
print(df)
Expected Output:
=== Adaeze's Weekly Fitness Log ===
duration_min calories heartrate
Monday 45 350 130
Tuesday 60 450 145
Wednesday 30 220 115
Thursday 55 420 140
Friday 40 310 125
Saturday 75 600 155
Sunday 20 160 105
Milestone achieved: A full, labelled DataFrame created from scratch.
Stage 2: Access Specific Days
# Stage 2: Access individual days using .loc
# Look at Saturday's full workout
print("\n=== Saturday's Workout ===")
print(df.loc["Saturday"])
# Compare Monday and Wednesday
print("\n=== Monday vs Wednesday ===")
print(df.loc[["Monday", "Wednesday"]])
Expected Output:
=== Saturday's Workout ===
duration_min 75
calories 600
heartrate 155
Name: Saturday, dtype: int64
=== Monday vs Wednesday ===
duration_min calories heartrate
Monday 45 350 130
Wednesday 30 220 115
Milestone achieved: Targeted row access using named labels.
Stage 3: Extract Individual Series (Columns)
Each column in a DataFrame is itself a Series. You can extract any column like this:
# Stage 3: Extract columns as Series
# Get all daily calorie values
calories_series = df["calories"]
print("\n=== Daily Calories ===")
print(calories_series)
Expected Output:
=== Daily Calories ===
Monday 350
Tuesday 450
Wednesday 220
Thursday 420
Friday 310
Saturday 600
Sunday 160
Name: calories, dtype: int64
Milestone achieved: Extracting a single column as a Series.
Stage 4: Simple Analysis
# Stage 4: Basic statistics on the data
print("\n=== Fitness Summary ===")
print("Total calories burned this week:", df["calories"].sum())
print("Average workout duration:", df["duration_min"].mean(), "minutes")
print("Highest heart rate recorded:", df["heartrate"].max())
print("Lowest calorie day value:", df["calories"].min())
print("Best workout day (most calories):", df["calories"].idxmax())
Expected Output:
=== Fitness Summary ===
Total calories burned this week: 2510
Average workout duration: 46.43 minutes
Highest heart rate recorded: 155
Lowest calorie day value: 160
Best workout day (most calories): Saturday
Milestone achieved: Using built-in Pandas methods (.sum(), .mean(), .max(), .min(), .idxmax()) to extract useful insights.
Stage 5: Save the Data as CSV (Optional Extension)
# Stage 5: Export to CSV for future use
df.to_csv("adaeze_fitness_log.csv")
print("\nFitness log saved to adaeze_fitness_log.csv!")
You can then reload it with:
df_loaded = pd.read_csv("adaeze_fitness_log.csv", index_col=0)
print(df_loaded)
Reflection questions:
- What do you notice about the
index_col=0argument inread_csv()? - What would happen if you left that argument out?
- Can you add an 8th day (“Monday Week 2”) to the DataFrame and recalculate the total calories?
Optional advanced extension: Add a column "intensity" where you classify each workout as "Low", "Medium", or "High" based on the calorie count, then display the updated DataFrame.
Section 9: Common Beginner Mistakes
Mistake 1: Forgetting import pandas as pd
# WRONG — Pandas not imported
df = pd.DataFrame({"a": [1, 2, 3]})
Error:
NameError: name 'pd' is not defined
Fix: Always start your file with import pandas as pd.
# CORRECT
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3]})
Mistake 2: Single Brackets vs Double Brackets with .loc
import pandas as pd
data = {"calories": [420, 380, 390], "duration": [50, 40, 45]}
df = pd.DataFrame(data)
# This returns a Series (one row)
print(df.loc[0])
# This returns a DataFrame (still one row but in table format)
print(df.loc[[0]])
Output comparison:
df.loc[0] → Series (vertical display)
df.loc[[0]] → DataFrame (horizontal table display)
Use double brackets when you want to keep the table structure intact.
Mistake 3: Mixing Up List and Dictionary Formats
# WRONG — passing a flat list to pd.DataFrame creates an error
import pandas as pd
df = pd.DataFrame([1, 2, 3]) # This actually works but creates something unexpected
print(df)
Output:
0
0 1
1 2
2 3
This creates a DataFrame with one column (named 0) and the numbers as rows. This is rarely what you intend. The proper way to create a meaningful DataFrame is using a dictionary:
# CORRECT
import pandas as pd
df = pd.DataFrame({"values": [1, 2, 3]})
print(df)
Output:
values
0 1
1 2
2 3
Mistake 4: Wrong File Path for CSV/JSON
import pandas as pd
df = pd.read_csv('myfile.csv')
Error:
FileNotFoundError: [Errno 2] No such file or directory: 'myfile.csv'
Causes and fixes:
- The file doesn’t exist → create or download the file
- The file is in a different folder → provide the full path, e.g.,
pd.read_csv('/home/user/data/myfile.csv') - Wrong file extension → check you’re not accidentally trying to read a
.txtfile as.csv
Mistake 5: Accessing an Index That Doesn’t Exist
import pandas as pd
a = [10, 20, 30]
s = pd.Series(a)
print(s[5]) # There is no index 5 — only 0, 1, 2 exist
Error:
KeyError: 5
Fix: Always check the length of your Series first with len(s) or print the Series to see its valid indexes before accessing.
Mistake 6: Confusing .loc Label Access with .iloc Position Access
Pandas has two ways to access rows:
.loc["label"]— access by label (the name you gave the index).iloc[2]— access by position (the numeric position, always starting from 0)
If you have named indexes and you try to use a number with .loc, you might get unexpected results or errors.
import pandas as pd
data = {"value": [100, 200, 300]}
df = pd.DataFrame(data, index=["a", "b", "c"])
# Using .loc with label
print(df.loc["b"]) # Correct — uses label "b"
# Using .iloc with position
print(df.iloc[1]) # Correct — uses position 1 (which is "b")
Both give the same result here, but always know which one you need.
Section 10: Reflection Questions
Think carefully about each of these before moving on. These questions will test whether you truly understood the concepts — not just memorised the code.
-
You have a Python list
scores = [88, 72, 95, 60, 83]. If you createpd.Series(scores), what will be the index labels? How would you change the labels to["Alice", "Bob", "Carol", "David", "Eve"]? -
A friend creates a DataFrame and complains: “I accessed row 1 with
.loc[1]but I got a Series, not a table!” What would you tell them to do if they want a DataFrame back? -
You are working at a company and a colleague shares a file called
sales_data.csv. You have never seen the file. Write the two lines of Python code you would use to load it and print the full contents. -
What is the difference between a Series and a DataFrame? Use a real-world example to explain.
- You read a JSON file and get the following output:
Duration Pulse Calories 0 60 110 409 1 60 117 479How many rows does this DataFrame have? How many columns? What is the index of the last row?
-
You want to check Tuesday’s workout data from a DataFrame with days as row labels. What code would you write?
-
Why do we write
import pandas as pdinstead of justimport pandas? What benefit does the aliaspdprovide? - What happens to your CSV’s header row when Pandas loads the file? Where does it go?
Section 11: Completion Checklist
Before moving to the next lesson, confirm that you can do each of the following confidently. Tick each item mentally as you review it:
- I can explain what Pandas is and name at least three real-world fields where it is used
- I can install Pandas using
pip install pandas - I can write
import pandas as pdand explain why we use theas pdalias - I can check the version of Pandas with
pd.__version__ - I can create a Pandas Series from a list, with and without custom index labels
- I can access a value in a Series by its index number AND by its label
- I can create a Pandas Series from a Python dictionary
- I can create a Pandas DataFrame from a dictionary
- I understand the difference between a Series (one column) and a DataFrame (full table)
- I can use
.loc[index]to access a single row and return a Series - I can use
.loc[[index1, index2]]to access multiple rows and return a DataFrame - I can create a DataFrame with custom row index labels using the
indexparameter - I can load a CSV file into a DataFrame using
pd.read_csv('filename.csv') - I can print the full DataFrame using
df.to_string() - I understand why Pandas truncates large DataFrames and how to change this with
pd.options.display.max_rows - I can load a JSON file into a DataFrame using
pd.read_json('filename.json') - I can build a Python dictionary and convert it directly to a DataFrame (simulating JSON loading)
- I completed the weekly fitness tracker mini-project
Lesson Summary
In this lesson, you took your first major steps into the world of data analysis with Python using Pandas.
Here is everything you covered:
What is Pandas? A Python library created in 2008 for analysing, cleaning, exploring, and manipulating data. It is used in data science, finance, healthcare, engineering, and beyond.
Getting Started: Install with pip install pandas. Always import with import pandas as pd. Check your version with pd.__version__.
Pandas Series: A one-dimensional array of data — like a single column in a spreadsheet. Created from lists or dictionaries. Supports numeric and custom index labels. Accessed by position or label using series[index].
Pandas DataFrame: A two-dimensional table with rows and columns. Created from a Python dictionary where keys become column headers. Rows can have numbered or named index labels. Use df.loc[label] for a single row (returns Series) and df.loc[[label1, label2]] for multiple rows (returns DataFrame).
Reading CSV Files: Use pd.read_csv('file.csv') to load any CSV file into a DataFrame instantly. Use .to_string() to display the full table. Control display rows with pd.options.display.max_rows.
Reading JSON Files: Use pd.read_json('file.json') to load JSON data. Since JSON and Python dictionaries share the same structure, you can also pass a nested dictionary directly to pd.DataFrame().
Mini-Project: You built a complete weekly fitness tracker that stores, accesses, and analyses real data using everything from this lesson.
You now have the foundation to work with real data in Python. In the next lesson, you will go deeper — learning how to analyse, clean, and draw conclusions from data using Pandas.
💡 Final thought: Every data scientist, machine learning engineer, and analyst uses Pandas daily. What you learned in this lesson is not just a beginner concept — it is production-level knowledge used by professionals worldwide. Well done!