NumPy and pandas basics
Building a DataFrame
A DataFrame is a NumPy array's more presentable sibling — named columns, mixed types across columns, and a lot of built-in convenience.
1Learn the idea
Read
Building one from scratch
The most common way to construct a small DataFrame is from a dictionary, where each key becomes a column name and each value is the data for that column:
import pandas as pd
df = pd.DataFrame({
"name": ["Ada", "Lin", "Sam"],
"score": [88, 92, 79],
})
print(df)
name score
0 Ada 88
1 Lin 92
2 Sam 79
That leftmost unlabeled column is the index — a row identifier pandas adds automatically (here, just 0, 1, 2) unless you set something more meaningful, like a student ID.
Read
Inspecting a DataFrame
A handful of methods answer almost every "what does this look like" question you'll have early on:
df.shape # (3, 2) — rows, columns, same idea as NumPy
df.columns # Index(['name', 'score'], dtype='object')
df.dtypes # the type pandas inferred for each column
df.head(2) # first 2 rows — essential once a table has thousands
df.describe() # count, mean, std, min/max for numeric columns
df.describe() in particular is worth running on any new dataset immediately — it's a fast sanity check for obviously wrong data (a negative age, a score of 1000 out of 100) before you do anything else with it.
Read
Selecting columns
df["score"] # one column, returned as a pandas Series
df[["name", "score"]] # multiple columns, returned as a DataFrame (note the double brackets)
The double-bracket form is a common early stumbling block: df["name", "score"] (single brackets, comma inside) raises an error, while df[["name", "score"]] (a list inside brackets) is the correct way to select several columns at once.
Read
Adding a computed column
New columns are created just by assigning to a name that doesn't exist yet:
df["pass"] = df["score"] >= 80
print(df)
name score pass
0 Ada 88 True
1 Lin 92 True
2 Sam 79 False
This is the same vectorized comparison from the previous page — df["score"] >= 80 — applied to a DataFrame column (which is really a pandas Series, a labeled 1D array built on NumPy underneath) instead of a plain array.
Read
Sorting and ranking a DataFrame
Once a table exists, a common next question is "who's on top?" — sort_values handles this directly:
df.sort_values("score", ascending=False)
This returns a new DataFrame ordered by score, highest first, without changing df itself unless you pass inplace=True (generally worth avoiding while learning — an explicit reassignment like df = df.sort_values(...) is easier to reason about later when reading your own code back). Sorting by more than one column works the same way with a list: df.sort_values(["class", "score"], ascending=[True, False]) sorts by class first, then by score (highest first) within each class.
Read
Renaming columns without rebuilding the table
Real datasets often arrive with column names that don't match your code's conventions — Student Name instead of name, or an all-caps SCORE. Renaming avoids either fighting the original names everywhere or rebuilding the DataFrame from scratch:
df = df.rename(columns={"Student Name": "name", "SCORE": "score"})
This is worth doing immediately after loading a messy real-world file, before writing any other code against it — consistent column names make every later line easier to read and less error-prone to type.
Go deeper
Before you start
Why this matters
NumPy arrays are excellent for numeric math, but real datasets rarely contain just one uniform block of numbers — a dataset of students has names (text) alongside scores (numbers) alongside a pass/fail flag (boolean). Pandas' DataFrame is built to hold exactly this: a table where each column has its own consistent type, but different columns can hold different types side by side, all addressable by name instead of numeric position.
In the wild
See how this idea shows up as a product and a company — then come back to the lesson. Skills transfer across vendors.