Sunday, 06 September 2026
Advertisement Advertise Your advert could be here Reach thousands of learners and ICT professionals across Rwanda. Contact us
Advertisement Opportunity Jobs, scholarships & hackathons Fresh openings from Rwandan job boards are pulled in every hour. See openings

Series, DataFrames and the index

Python data analysis with pandas · lesson 2 of 12

In this lesson: Create DataFrames from several sources and manage the index deliberately.

You will usually load a DataFrame from a file, but building one by hand is how you test an idea in five seconds.

Three ways to build one

import pandas as pd

# from a dict of columns  -- the most common
df = pd.DataFrame({
    "name":     ["Aline", "Jean", "Uwase"],
    "district": ["Gasabo", "Huye", "Gasabo"],
    "mark":     [78, 41, 65],
})

# from a list of records (rows) -- what an API usually returns
rows = [
    {"name": "Aline", "mark": 78},
    {"name": "Jean",  "mark": 41},
]
df2 = pd.DataFrame(rows)

# from a list of lists, with explicit column names
df3 = pd.DataFrame([["Aline", 78], ["Jean", 41]], columns=["name", "mark"])

Looking at the shape

df.shape        # (3, 3)  -- rows, columns
df.columns      # Index(['name', 'district', 'mark'], dtype='object')
df.dtypes       # the type of each column
df.index        # RangeIndex(start=0, stop=3, step=1)

Picking columns

df["mark"]                  # one column -> a Series
df[["name", "mark"]]        # several columns -> a DataFrame
One bracket gives a Series, two brackets give a DataFrame. That is the single most common source of "why does this look different?" — df["mark"] and df[["mark"]] hold the same numbers in different container types.

Adding and removing columns

df["passed"] = df["mark"] >= 50          # a boolean column, computed
df["final"] = (df["mark"] * 1.1).round(1)
df["grade"] = pd.cut(df["mark"], bins=[0, 49, 69, 100],
                     labels=["Fail", "Pass", "Distinction"])

df = df.drop(columns=["final"])           # remove
df = df.rename(columns={"mark": "term_mark"})

pd.cut turns a numeric column into labelled bands — age groups, grade bands, price brackets. You will use it constantly.

The index, taken seriously

By default the index is 0, 1, 2… You can make a meaningful column the index instead:

df = df.set_index("name")
print(df.loc["Jean"])          # look a row up by its label

df = df.reset_index()          # push it back to being a normal column

Two rules worth learning now:

  • After filtering, the index keeps the original numbers — rows 0, 3, 7. That is deliberate: it tells you where the rows came from. Call .reset_index(drop=True) when you want a clean 0..n again.
  • Two DataFrames combine on the index, not on row position. Mismatched indexes are why an arithmetic result can come out full of NaN.

Copies and views

small = df[df["mark"] > 50]          # may be a view onto df
small["bonus"] = 5                    # SettingWithCopyWarning

small = df[df["mark"] > 50].copy()   # explicit copy -- no warning
small["bonus"] = 5                    # safe

SettingWithCopyWarning means pandas cannot tell whether you meant to change the original. Add .copy() when you slice a subset you intend to modify, and the warning disappears for good.

Try it yourself

Build a ten-row DataFrame of students with name, district and mark. Add a passed boolean and a banded grade column with pd.cut. Set name as the index, look one student up with .loc, then reset the index.

Create a free account to save progress

All lessons in this track

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
    Selecting and filtering rows ~30 min account needed
  6. 6
  7. 7
    Cleaning types, text and dates ~30 min account needed
  8. 8
    groupby: the heart of analysis ~30 min account needed
  9. 9
    Joining and combining tables ~30 min account needed
  10. 10
    Reshaping: pivot, melt and crosstab ~25 min account needed
  11. 11
    Charts that get read ~30 min account needed
  12. 12
Advertisement Yanjye Learn a new digital skill this week ICT, programming and professional courses with graded weekly assignments. Start free