BitBootcampBitBootcamp ← all explainers 🔄 Review ⚙ Settings

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