Chapter 1 · Part 1

Setup & the DataFrame

If NumPy is the grid of numbers, pandas is the spreadsheet: rows, named columns, mixed types, missing values and all. It's the first tool a data analyst or data scientist reaches for, and it sits directly on top of NumPy. This is a hands-on course — every chapter ends with a puzzle you solve before peeking. Keep a Python shell open and play along.

Install it

One dependency (it pulls in NumPy for you). Make a virtual environment and install pandas:

terminal
python3 -m venv .venv
source .venv/bin/activate     # Windows: .venv\Scripts\Activate.ps1
pip install pandas

By convention, pandas is always imported as pd. This course targets pandas 3.0 (what pip install pandas gives you today); on older versions a few labels differ — text columns show object where 3.0 shows str.

import pandas as pd

Two data structures

pandas has exactly two you need to know. A Series is a single column: a 1-D array of values with a labelled index. A DataFrame is a whole table: a set of Series sharing one index — this is what you'll work with 95% of the time.

The easiest way to make a DataFrame is from a dictionary, where each key is a column name and each value is the column's data. Here's the small movies table we'll use all course:

movies.py
import pandas as pd

movies = pd.DataFrame({
  "title":  ["Inception", "The Matrix", "Interstellar", "Parasite",
             "Whiplash", "Dune", "La La Land", "Coco"],
  "year":   [2010, 1999, 2014, 2019, 2014, 2021, 2016, 2017],
  "genre":  ["Sci-Fi", "Sci-Fi", "Sci-Fi", "Thriller",
             "Drama", "Sci-Fi", "Drama", "Animation"],
  "rating": [8.8, 8.7, 8.6, 8.5, 8.5, 8.0, 8.0, 8.4],
  "votes":  [2400, 1900, 1800, 780, 900, 650, 560, 520],
})

print(movies)
output
title  year      genre  rating  votes
0     Inception  2010     Sci-Fi     8.8   2400
1    The Matrix  1999     Sci-Fi     8.7   1900
2  Interstellar  2014     Sci-Fi     8.6   1800
3      Parasite  2019   Thriller     8.5    780
4      Whiplash  2014      Drama     8.5    900
5          Dune  2021     Sci-Fi     8.0    650
6    La La Land  2016      Drama     8.0    560
7          Coco  2017  Animation     8.4    520

That bold left column of 0…7 is the index — pandas gives every row a label, defaulting to its position. Pull out one column and you get a Series back:

type(movies["title"])   # <class 'pandas.Series'>

Look before you leap

You'll rarely print a whole table — real datasets have thousands of rows. Instead you peek. Four methods you'll use constantly:

inspect.py
movies.head(3)   # the first 3 rows (default 5)
movies.shape     # (8, 5)  — 8 rows, 5 columns
movies.dtypes    # the type of each column
movies.info()    # a full summary: columns, non-null counts, dtypes

info() is the one to run first on any new dataset — it tells you how big it is, what the columns are, and (crucially, for Chapter 4) how many values are missing:

movies.info()
<class 'pandas.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 5 columns):
#   Column  Non-Null Count  Dtype
---  ------  --------------  -----
0   title   8 non-null      str
1   year    8 non-null      int64
2   genre   8 non-null      str
3   rating  8 non-null      float64
4   votes   8 non-null      int64
dtypes: float64(1), int64(2), str(2)
🎯 Your turn
Build a DataFrame called fruit with two columns — name ('apple', 'banana', 'cherry') and price (0.5, 0.3, 2.0) — then print its shape.

You've got a table. Next, let's reach into it.