LevelUpWith

Explore / pandas for Spreadsheet Analysts: Clean, Join, Reconcile / Lesson 1

Lesson 1: Your First Notebook: Series and DataFrames

Set up a Jupyter or VS Code notebook, import pandas and check its version, then build a small Series and DataFrame by hand and see how they map to a spreadsheet's columns, rows and row labels.

Free to read, no account needed. Part of pandas for Spreadsheet Analysts: Clean, Join, Reconcile.

By the end of this level you'll be able to

  • Create and run a notebook in Jupyter or VS Code, and print pd.__version__ to confirm whether you are on pandas 2.x or 3.0
  • Build a Series and a DataFrame from a Python dict, and identify the index, the columns and the dtypes
  • Explain how a DataFrame differs from a spreadsheet range, for example labelled rows and one dtype per column

Why start here

In a spreadsheet you can see your data the moment you open the file. In pandas you see it only after you write code to load or build it. It feels odd at first. The payoff is that every step you take gets written down, and you can run the whole thing again next month with a fresh export. In this level you'll set up a notebook, check your pandas version and build two structures by hand: the Series, which is like one labelled column, and the DataFrame, which is like a sheet. Once you understand how these two map to columns, rows and row labels, everything later in the course is easier.

Step 1: Get a notebook running

A notebook is a document made of cells. Each cell holds code that you run on its own, and the output shows up underneath. That makes it feel like a spreadsheet: you change something and see the result straight away.

Option A: JupyterLab in the browser

# In a terminal (PowerShell, Terminal, etc.)
python -m pip install jupyterlab pandas   # installs JupyterLab and pandas
python -m jupyter lab                     # opens JupyterLab in your browser

The python -m form makes sure you use the same Python that you installed into. It also avoids many "jupyter is not recognized" PATH errors on Windows.

Option B: VS Code

  1. Install the Jupyter extension (and the Python extension, if you don't have it).
  2. Install pandas and ipykernel into the Python environment you want to use: python -m pip install pandas ipykernel. VS Code needs only ipykernel to run Python as a notebook kernel. You don't need the full Jupyter package.
  3. Press Ctrl+Shift+P and run Create: New Jupyter Notebook, or just create a file ending in .ipynb.
  4. Click Select Kernel at the top right and pick that environment.

To run a cell, press Shift+Enter. That runs the cell and moves you to the next one. Ctrl+Enter runs the cell and leaves you where you are.

Gotcha: if import pandas says ModuleNotFoundError, the kernel is almost always a different Python from the one you installed pandas into. Check which kernel is selected before you reinstall anything.

Step 2: Import pandas and check the version

import pandas as pd          # 'pd' is the universal convention; use it
print(pd.__version__)        # e.g. '3.0.6' or '2.2.3'

This matters because pandas 3.0 (released January 2026) changed some default behaviour that this course will point out as it comes up. The change you'll see first: in pandas 3.0, text columns get a dedicated str dtype, while in pandas 2.x they show as object. Copy-on-Write also became the default in 3.0. It affects how changes to a subset behave, and we'll deal with it when we start modifying data. pandas 3.0 needs Python 3.11 or later.

In every new analysis, put the version print in the first cell. If someone else gets different results, the version is the first thing you'll compare.

Step 3: A Series is one labelled column

# Monthly sales by region, as a plain Python dict
sales = pd.Series({"North": 1200, "South": 950, "East": 1430}, name="sales")
sales
North    1200
South     950
East     1430
Name: sales, dtype: int64

There are three parts to read here:

  • Index: the labels on the left (North, South, East). When you build a Series from a dict, the keys become the index.
  • Values: the numbers on the right.
  • dtype: one data type for the whole Series, here int64 (whole numbers).
sales.index     # Index(['North', 'South', 'East'], dtype='str')  (dtype='object' on 2.x)
sales.dtype     # dtype('int64')

In spreadsheet terms, a Series is like column B with column A's labels permanently attached. If you sort or filter the values, each label stays with its value.

Step 4: A DataFrame is a sheet of Series

Pass a dict of lists to build a DataFrame. Each key becomes a column header, and each list becomes that column's values.

invoices = pd.DataFrame({
    "invoice_id": ["INV-001", "INV-002", "INV-003"],
    "customer":   ["Acme Ltd", "Brightwater", "Cole & Co"],
    "amount":     [1200.0, 950.5, 1430.0],
    "paid":       [True, False, True],
})
invoices
  invoice_id     customer  amount   paid
0    INV-001     Acme Ltd  1200.0   True
1    INV-002  Brightwater   950.5  False
2    INV-003    Cole & Co  1430.0   True

The 0, 1, 2 on the left is the index. You didn't supply one, so pandas made a default RangeIndex that counts from 0. Let's inspect each part:

invoices.index    # RangeIndex(start=0, stop=3, step=1)
invoices.columns  # Index(['invoice_id', 'customer', 'amount', 'paid'], dtype='str')
invoices.dtypes
invoice_id        str      <- 'object' on pandas 2.x
customer          str      <- 'object' on pandas 2.x
amount        float64
paid             bool
dtype: object

(That last dtype: object line describes the list of dtypes itself. You can ignore it.)

In a spreadsheet the row labels are fixed row numbers. In pandas you can supply meaningful row labels instead:

invoices_by_id = pd.DataFrame(
    {"customer": ["Acme Ltd", "Brightwater", "Cole & Co"],
     "amount":   [1200.0, 950.5, 1430.0]},
    index=["INV-001", "INV-002", "INV-003"],   # row labels instead of 0, 1, 2
)

All the lists must be the same length. If they aren't, pandas raises a ValueError and won't guess.

How this differs from a spreadsheet range

Spreadsheet pandas DataFrame
Any cell can hold anything One dtype per column
Rows are numbered 1, 2, 3 by position Rows have an index, which can be meaningful labels
Headers are just the first row of data Column names are separate from the data
Formulas live in cells Calculations live in code you can rerun

One dtype per column has a cost when your data is messy:

pd.Series([100, "n/a", 250]).dtype   # dtype('O') -> object: mixed types

One stray "n/a" turns the whole column into object, so it's no longer numeric, and maths on it will fail or behave oddly. In a spreadsheet that cell would just sit there quietly. pandas makes the problem show up in the dtype, which is useful. Get into the habit of checking .dtypes.

Check your work

Run this cell. It should print True three times:

print(list(invoices.columns) == ["invoice_id", "customer", "amount", "paid"])
print(invoices["amount"].dtype == "float64")
print(list(sales.index) == ["North", "South", "East"])

Key takeaways

  • A notebook runs code in cells. Use Shift+Enter, and make sure the kernel is the Python where pandas is installed.
  • Put print(pd.__version__) in your first cell. On 3.0 text columns show as str, on 2.x as object.
  • A Series is one column with an index and a single dtype. Built from a dict, its keys become the index.
  • A DataFrame is a table of columns. A dict of lists gives you column names from the keys and a default 0-based RangeIndex.
  • Unlike a spreadsheet, each column has one dtype, and rows have an index of labels, not just positions.

A 6-question knowledge check follows this lesson in the app, free and without an account.

More like this

  • dbt in the AI Era: Migrating from Legacy ETL

    Move a legacy estate of stored procedures, scheduled SQL and graphical ETL jobs into tested, documented and version-controlled dbt models, then cut over withou…

    Beyond the Docs · Data & Analytics · Expert · 60 levels · 4 free · Professionally curated by levelupwith.com

  • Google Cloud Associate Data Practitioner Exam Prep

    Prepare for Google Cloud's Associate Data Practitioner exam by working through every item in Google's exam guide. You will prepare and ingest data, analyse it…

    Exam prep · Google · Data & Analytics · Capable · 20 levels · 4 free · Professionally curated by levelupwith.com

  • Microsoft Fabric Analytics Engineer (DP-600) Exam Prep

    Prepare for Microsoft DP-600 under the skills measured as of October 19, 2026. The course covers every bullet in Microsoft's free study guide on Microsoft Lear…

    Exam prep · DP-600 · Data & Analytics · Expert · 48 levels · 4 free · Professionally curated by levelupwith.com

  • Copilot Across Fabric, Power BI and Microsoft 365

    Make your Power BI semantic models and Fabric data AI-ready, then set up Copilot, Fabric data agents and Microsoft 365 Copilot so colleagues get trustworthy, p…

    Course · Microsoft · Data & Analytics · Capable · 19 levels · 4 free · Professionally curated by levelupwith.com

  • Microsoft Fabric for Power BI Analysts

    Build a complete sales solution in a Fabric trial workspace, taking raw files through a lakehouse, a warehouse, Dataflows Gen2, pipelines and notebooks to a Di…

    Course · Microsoft · Data & Analytics · Capable · 20 levels · 4 free · Professionally curated by levelupwith.com

  • Power Query and Power BI Data Modelling That Adds Up

    Fix messy source data in Power Query and build a clean star-schema model in Power BI, so your totals come out right and your reports stay fast. Each level fixe…

    Course · Microsoft · Data & Analytics · Capable · 20 levels · 4 free · Professionally curated by levelupwith.com