PD-01-004-P · Primer — Inspecting a DataFrame
The idea in one sentence
Before you analyze a table, you look at it — head, info, describe, and shape are the four quick glances that tell you what you're holding.
Why it exists
Real datasets are too big to read row by row — you might have 2 million rows and 40 columns, and scrolling through them tells you nothing. You need a way to size up a table in seconds: How big is it? What are the columns called? Are the numbers text or real numbers? Is anything missing? These four tools answer exactly those questions without printing the whole thing. Think of them as the pat-down you do the moment data lands on your desk: you always run them first, before writing a single line of real analysis. They exist so you never work blind — and so you catch problems (wrong types, missing values, surprise row counts) while they're still cheap to fix.
How it works
Each tool answers one question. df.shape gives you (rows, columns) as a plain tuple — the size of the table. df.head(n) prints the first n rows (default 5) so you can see what the data actually looks like. df.info() lists every column with its data type and how many non-null values it has — your check for missing data and wrong types. df.describe() computes summary statistics (count, mean, min, max, quartiles) for the numeric columns only. You call them on any DataFrame, and they never change your data — they only report on it. Run all four the moment a table arrives, and you'll know what you're dealing with.
import pandas as pd
df = pd.DataFrame({
"city": ["Austin", "Denver", "Miami", "Boise"],
"temp_f": [98, 84, 91, 79],
"humid": [42, 30, 88, 25],
})
print(df.shape) # (4, 3) -> 4 rows, 3 columns
print(df.head(2)) # first 2 rows:
# city temp_f humid
# 0 Austin 98 42
# 1 Denver 84 30
print(df.describe()) # numeric summary (temp_f, humid):
# temp_f humid
# count 4.000000 4.000000
# mean 88.000000 46.250000
# min 79.000000 25.000000
# max 98.000000 88.000000 (rows 25%/50%/75%/std omitted here)
The one gotcha
head and shape are attributes/methods you print, but info() prints on its own and returns nothing — so x = df.info() leaves x empty (None). Just call df.info() on its own line; don't try to capture or print() its result. And remember df.shape has no parentheses (it's an attribute), while df.head() and df.describe() need parentheses (they're methods) — df.shape() will error, and df.head without () shows the method object instead of your rows.
See it — the four glances, one table
flowchart TD
D["DataFrame<br/>(4 rows x 3 cols)"]
D --> A["df.shape<br/>-> (4, 3)"]
D --> B["df.head(2)<br/>-> first 2 rows"]
D --> C["df.info()<br/>-> types + non-null"]
D --> E["df.describe()<br/>-> numeric stats"]
A --> Q["You now know:<br/>size, look, types,<br/>and ranges"]
B --> Q
C --> Q
E --> Q
The one-line takeaway
Land a table, run shape, head, info, describe — in that order — and you'll never analyze data you haven't looked at.
Where you'll meet it
Every single pandas session starts here: you read a CSV, then immediately inspect it to confirm the rows loaded, the columns are named right, and the numbers came in as numbers (not text). You'll lean on info() to spot missing values before they break a calculation, and on describe() to sanity-check that a "price" column isn't secretly holding negative numbers or wild outliers.
Named concepts: head, info, describe, shape
