Inspecting Data: head, tail, info, describe
Reviewed & published by Brayan K
Inspecting data means using Pandas' built-in summary methods — head, tail, info, and describe — to get a fast, reliable overview of a dataset's contents, structure, and statistics before you analyse it.
Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Never trust data you haven't looked at. These methods are the first thing every analyst runs on a fresh dataset.
What You'll Learn in This Lesson
- Preview rows with head() and tail()
- Check structure and missing data with info()
- Summarise numbers with describe()
- Read size with shape, columns, dtypes
- Count distinct values with nunique()
- Tally categories with value_counts()
1 Previewing Rows: head() and tail()
Real datasets can have thousands of rows. df.head() shows the first 5 and df.tail() shows the last 5 — a quick peek without flooding your screen:
df.head() # first 5 rows
df.head(3) # first 3 rows
df.tail(2) # last 2 rowsimport pandas as pd
df = pd.DataFrame({
"name": ["Ana", "Ben", "Cara", "Dan", "Eve", "Finn"],
"score": [88, 72, 95, 60, 79, 84],
})
print(df.head(3)) # first 3 rows
print(df.tail(2)) # last 2 rows
# Output:
# name score
# 0 Ana 88
# 1 Ben 72
# 2 Cara 95
# name score
# 4 Eve 79
# 5 Finn 84
# ✅ Expected output:
# name score
# 0 Ana 88
# 1 Ben 72
# 2 Cara 95
# name score
# 4 Eve 79
# 5 Finn 842 Structure: info(), shape, columns, dtypes
df.info() prints a compact summary of the DataFrame's structure: how many rows, each column's name, its non-null count (great for spotting missing data), and its dtype.
- df.shape — (rows, columns)
- df.columns — the column names
- df.dtypes — the type of each column
import pandas as pd
df = pd.DataFrame({
"name": ["Ana", "Ben", "Cara"],
"score": [88, 72, 95],
"passed": [True, True, True],
})
df.info()
# Output:
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 3 entries, 0 to 2
# Data columns (total 3 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 name 3 non-null object
# 1 score 3 non-null int64
# 2 passed 3 non-null bool
# dtypes: bool(1), int64(1), object(1)
# memory usage: 179.0+ bytes
# ✅ Expected output:
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 3 entries, 0 to 2
# Data columns (total 3 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 name 3 non-null object
# 1 score 3 non-null int64
# 2 passed 3 non-null bool
# dtypes: bool(1), int64(1), object(1)
# memory usage: 183.0+ bytes3 Statistics: describe(), nunique(), value_counts()
df.describe() computes summary statistics for every numeric column — count, mean, standard deviation, min, the three quartiles, and max:
df.describe() # numeric summary stats
df.nunique() # distinct values per column
df["city"].value_counts() # tally of each categorynunique() tells you how many distinct values a column has, while value_counts() tallies how many times each value appears — ideal for category columns.
import pandas as pd
df = pd.DataFrame({
"city": ["London", "Paris", "London", "Berlin", "Paris", "London"],
"temp": [15, 18, 14, 12, 19, 16],
})
print(df["city"].value_counts()) # tally each city
print()
print("Distinct cities:", df["city"].nunique())
print("Mean temp:", df["temp"].mean())
# Output:
# city
# London 3
# Paris 2
# Berlin 1
# Name: count, dtype: int64
#
# Distinct cities: 3
# Mean temp: 15.666666666666666
# ✅ Expected output:
# city
# London 3
# Paris 2
# Berlin 1
# Name: count, dtype: int64
#
# Distinct cities: 3
# Mean temp: 15.666666666666666import pandas as pd
df = pd.DataFrame({
"name": ["Ana", "Ben", "Cara", "Dan"],
"score": [88, 72, 95, 60],
})
# 🎯 YOUR TURN: print the numeric summary statistics
# Replace ___ with the right method name
print(df.___())
# Expected output (rows: count, mean, std, min, 25%, 50%, 75%, max):
# score
# count 4.000000
# mean 78.750000
# std 15.305773
# min 60.000000
# 25% 69.000000
# 50% 80.000000
# 75% 89.750000
# max 95.000000📋 Quick Reference
| Method | Tells You |
|---|---|
| df.head() / df.tail() | First / last rows |
| df.shape | (rows, columns) |
| df.info() | Types, non-null counts, memory |
| df.describe() | Numeric summary statistics |
| df.nunique() | Distinct values per column |
| df["col"].value_counts() | Tally of each value |
🎯 Mini Challenge: Quick Audit
Run a four-step audit on a small dataset:
- Print the shape
- Preview the first 2 rows with head(2)
- Print describe() for the numbers
- Tally the team column with value_counts()
import pandas as pd
df = pd.DataFrame({
"player": ["Ana", "Ben", "Cara", "Dan"],
"team": ["Red", "Blue", "Red", "Blue"],
"points": [10, 7, 13, 9],
})
print("Shape:", df.shape)
print(df.head(2))
print(df["team"].value_counts())
# Output:
# Shape: (4, 3)
# player team points
# 0 Ana Red 10
# 1 Ben Blue 7
# team
# Red 2
# Blue 2
# Name: count, dtype: int64
# ✅ Expected output:
# Shape: (4, 3)
# player team points
# 0 Ana Red 10
# 1 Ben Blue 7
# team
# Red 2
# Blue 2
# Name: count, dtype: int64❓ Frequently Asked Questions
Lesson complete — you can audit any dataset!
You can preview rows with head and tail, check structure and missing data with info, summarise numbers with describe, and tally categories with nunique and value_counts.
Practice quiz
How many rows does df.head() show by default?
- 10
- 5
- 3
- All of them
Answer: 5. df.head() returns the first 5 rows by default.
What does df.tail(2) return?
- The first 2 rows
- Every other row
- The last 2 rows
- 2 random rows
Answer: The last 2 rows. tail(n) shows the last n rows; tail(2) shows the final two.
Which method summarises structure: column names, non-null counts, and dtypes?
- df.describe()
- df.head()
- df.value_counts()
- df.info()
Answer: df.info(). df.info() reports structure, non-null counts, dtypes, and memory usage.
Which method gives count, mean, std, min, quartiles, and max for numeric columns?
- df.describe()
- df.info()
- df.shape
- df.head()
Answer: df.describe(). df.describe() computes summary statistics for numeric columns.
What does df.shape return?
- The column names
- A tuple of (rows, columns)
- The dtypes
- The memory usage
Answer: A tuple of (rows, columns). df.shape is a (rows, columns) tuple.
What does df['col'].value_counts() do?
- Returns the column mean
- Sorts the column
- Tallies how many times each distinct value appears
- Counts the columns
Answer: Tallies how many times each distinct value appears. value_counts() counts occurrences of each value, sorted high to low.
What does df.nunique() report?
- The total row count
- The mean of each column
- The sum per column
- The number of distinct values per column
Answer: The number of distinct values per column. nunique() returns how many distinct values each column has.
What does df.info() return as its value?
- None (it prints the summary)
- A DataFrame
- A dictionary
- A list of dtypes
Answer: None (it prints the summary). info() prints its summary and returns None, so do not assign its result.
For scores [88, 72, 95, 60], what mean does describe() report?
- 78.75
- 80.0
- 72.0
- 95.0
Answer: 78.75. (88+72+95+60)/4 = 78.75.
What is the recommended first pair of methods to run on a new dataset?
- df.melt() and df.pivot()
- df.groupby() and df.agg()
- df.shape and df.head()
- df.drop() and df.fillna()
Answer: df.shape and df.head(). Start with df.shape and df.head() to see the size and a sample.
Continue this course
- Previous: Reading & Writing Data (CSV, Excel, JSON)
- Next: Selecting Columns and Rows — Pick out the exact columns and rows you need from a DataFrame
- Quick reference: Pandas cheat sheet › Inspecting
Frequently asked questions
What does df.head() do in Pandas?
df.head() returns the first 5 rows of a DataFrame so you can preview its contents without printing everything. Pass a number to change how many, e.g. df.head(10). df.tail() does the same for the last rows.
What is the difference between info() and describe()?
df.info() summarises structure — column names, non-null counts, dtypes, and memory usage. df.describe() summarises the numbers — count, mean, std, min, quartiles, and max for each numeric column. One is about shape, the other about statistics.
How do I count unique values in a column?
Use df['col'].value_counts() to count how many times each distinct value appears (sorted high to low), or df.nunique() to get just the number of distinct values per column.
Which inspection method should I run first on a new dataset?
Start with df.shape and df.head() to see the size and a sample, then df.info() to check types and missing values, and df.describe() to understand the numeric ranges. Those four give you a fast, reliable overview.