Inspect DataFrames with head and info
Learn how to use pandas' head() and info() methods to quickly preview and summarize your DataFrames. This lesson covers the core concepts, step-by-step usage, hands-on practice, and common troubleshooting tips to help you understand your data before diving into analysis.
Focus: inspect dataframes with head and info
You've just loaded a CSV file into a DataFrame and your screen flashes a wall of numbers, NaN values, and columns with names you don't recognize. You could scroll through every row, but with thousands or millions of records, that's a recipe for eye strain and poor judgment. This lesson solves that problem by teaching you two of pandas' most essential inspection tools: head() and info(). Master these, and you'll turn a chaotic data dump into a clear, structured snapshot in seconds — the first step of any successful data analysis.
The problem this lesson solves
Before you can analyze data, you need to understand what you're working with. Imagine being handed a spreadsheet with 50 columns and 100,000 rows. You have no idea what each column represents, whether there are missing values, or if the data types are even correct for the operations you plan to run. Diving straight into analysis without inspection is like flying a plane without checking the instrument panel — you're bound to crash.
The core pain this lesson addresses is the initial uncertainty every data scientist faces: What does this data look like? Without a quick, reliable way to preview and summarize your DataFrame, you'll waste time writing code that fails because of unexpected data types, hidden NaN values, or columns that don't exist. head() and info() are your first line of defense — they give you a fast, structured overview so you can make informed decisions about cleaning, transforming, and modeling your data.
Core concept / mental model
Think of a DataFrame as a spreadsheet with superpowers — you can zoom out to see the whole magical spreadsheet's structure.
head()is your preview lens. It shows you the first few rows (by default, five) so you can eyeball the data: column names, sample values, and what each row represents.info()is your x-ray machine. It scans the entire table and returns a concise summary: column names, data types, non-null counts, and memory usage.
Together, these two methods give you a two-part mental model:
- What's in the data? (head) — The rows you see are a sample of what to expect. This helps you detect obvious issues like misplaced values, unexpected formats, or columns that are entirely empty.
- What's the shape and health of the data? (info) — The summary tells you how many rows and columns exist, which columns contain missing values, and whether your data types are appropriate (e.g., integers stored as objects).
In a typical workflow, you'll call head() first to get a visual feel, then info() to assess structure and completeness. This pair is your quickest route from raw data to a confident starting point.
How it works step by step
Here's the logical sequence for inspecting any DataFrame with head() and info():
-
Load your DataFrame — You'll usually import pandas and read data from a CSV, Excel file, or database into a DataFrame variable, for example
df. -
Preview with
head()— Calldf.head(). By default, it outputs the first 5 rows. To see more or fewer, pass a number:df.head(10)shows the first 10 rows,df.head(1)shows the first row.
- Why first rows? They often represent a typical sample, but be cautious: if the data is sorted in a particular order, the first rows might not reflect the whole dataset. That's where
sample()(a related method) can help, buthead()is the standard starting point.
- Summarize with
info()— Calldf.info(). This prints a concise summary to the console usingsys.stdout. It includes:
- The class of the object (e.g.,
pandas.core.frame.DataFrame) - The RangeIndex (or other index type) and its length (number of rows)
- A list of each column with its non-null count and data type
- The memory usage of the entire DataFrame
-
Interpret the output — For each column, compare the non-null count to the total number of rows. If they differ, you have missing values. Check the data types: are they logical for each column? (Numbers should be
int64orfloat64, text should beobject, dates should bedatetime64.) -
Act on what you find — Based on the summary, you might decide to clean missing values, convert data types, or rename columns before proceeding with analysis.
Why these two are the perfect first step
- Speed: Both methods are fast, even on large DataFrames, because
head()only reads a slice andinfo()uses efficient internal metadata. - No assumptions: They don't require you to guess column names or data structures — they show you exactly what's there.
- Reproducibility: Your inspection commands can be saved in a notebook or script, making your exploration reproducible for others.
Hands-on walkthrough
Let's put theory into practice. We'll create a small DataFrame to simulate a real-world scenario — a sales dataset with customer information.
First, ensure you have pandas installed:
pip install pandas
Now, create a sample DataFrame and apply head() and info():
import pandas as pd
data = {
"customer_id": [101, 102, 103, 104, 105],
"name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"age": [25, 30, None, 35, 40],
"email": ["alice@example.com", "bob@example.com", "charlie@example.com", None, "eve@example.com"],
"purchase_amount": [250.50, 120.00, 89.99, 450.25, 320.00]
}
df = pd.DataFrame(data)
print("First 2 rows using head(2):")
print(df.head(2))
print("\nFull DataFrame info:")
df.info()
Expected output:
First 2 rows using head(2):
customer_id name age email purchase_amount
0 101 Alice 25.0 alice@example.com 250.5
1 102 Bob 30.0 bob@example.com 120.0
Full DataFrame info:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 customer_id 5 non-null int64
1 name 5 non-null object
2 age 4 non-null float64
3 email 4 non-null object
4 purchase_amount 5 non-null float64
dtypes: float64(2), object(2), int64(1)
memory usage: 328.0 bytes
Notice how age has only 4 non-null values — one missing (the None we inserted). Similarly, email is missing for Diana (row index 3). The data types are inferred: age becomes float64 because of the missing value, which is worth noting for later analysis.
Now, let's read a real CSV file to see how this works in practice. (You can create a file named sales_data.csv with the content below, or use any CSV you have.)
# sales_data.csv
order_id,product,quantity,price,total
1001,Widget A,2,19.99,39.98
1002,Gadget B,1,299.00,299.00
1003,Widget A,5,19.99,99.95
1004,Gadget B,3,299.00,897.00
1005,Widget C,10,4.50,45.00
# In Python:
import pandas as pd
df_sales = pd.read_csv("sales_data.csv")
print("Preview with head(3):")
print(df_sales.head(3))
print("\nThe info() summary:")
df_sales.info()
Expected output:
Preview with head(3):
order_id product quantity price total
0 1001 Widget A 2 19.99 39.98
1 1002 Gadget B 1 299.00 299.00
2 1003 Widget A 5 19.99 99.95
The info() summary:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 5
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 order_id 5 non-null int64
1 product 5 non-null object
2 quantity 5 non-null int64
3 price 5 non-null float64
4 total 5 non-null float64
dtypes: float64(2), int64(2), object(1)
memory usage: 328.0 bytes
Here, all columns have equal non-null counts, so the data is complete. The product column is an object dtype, which is fine for text.
Pro tip: Use
df.sample(5)instead ofhead()when you want a random sample of rows, especially if you're worried that the first rows are not representative.head()is best for a quick look at the top,sample()for a more balanced peek.
Combining head and info
In a typical exploratory script, you'll chain them like this:
import pandas as pd
df = pd.read_csv("your_large_dataset.csv")
# Step 1: Quick visual preview
df.head()
# Step 2: Structural summary
df.info()
Compare options / when to choose what
head() and info() are not the only inspection tools. Here's how they stack up against other common pandas commands:
| Method | What it shows | Best used when | Limitations |
|---|---|---|---|
head(n) |
First n rows | Quick visual preview of top rows | Might miss issues in the middle/tail |
info() |
Summary of columns, dtypes, non-null counts, memory | Understanding data structure and missing values | Doesn't show actual data values |
tail(n) |
Last n rows | Checking the end of the data (e.g., recent entries) | Only shows the tail, not the whole picture |
.shape |
Tuple (rows, columns) | Getting exact dimensions | No column details |
.describe() |
Descriptive statistics for numeric columns | Overview of distributions (mean, min, max) | Only numeric columns by default |
.sample(n) |
Random n rows | Checking representative rows without bias | Not deterministic unless you set a random seed |
When to choose what?
- Start with
head(10)to get a quick sense of the data. If the first rows look weird (e.g.,NaNeverywhere), you might need to investigate further. - Follow up with
info()to understand data types and missing values — this is critical before any data cleaning or modeling. - If you need to check the end of your data (e.g., time series where the latest rows matter), use
tail(5). - For a statistical summary of numeric columns, use
describe(). - For a random slice to check for potential issues anywhere in the dataset, use
sample(5).
Blockquote: In a data science project, always start with
head()andinfo(). They are the 'hello world' of data exploration — and they save you from countless headaches downstream.
Troubleshooting & edge cases
1. head() shows only the first few rows, but the data looks fine — is that enough?
Not always. The first rows may be sorted by a column (e.g., date) and not representative of the whole dataset. For example, if your data is sorted by date, the top rows are the oldest entries, which might have different missing-value patterns. Use sample() to get a random look.
2. info() reports NaN in a numeric column — why is the dtype float64?
When pandas encounters a missing value in a column of integers, it automatically converts that column to float64 because integers cannot hold NaN. This is a common gotcha. After cleaning the missing values, you can convert the column back to int64 using .astype('int64').
3. The info() output shows a column with object dtype, but it looks like a date.
Pandas doesn't automatically parse dates unless you specify parse_dates in read_csv or use pd.to_datetime(). If you need date operations, convert it explicitly.
4. I have thousands of columns — info() prints them all, and it's overwhelming.
That's normal. You can also use df.columns to list column names, or df.dtypes to see just the dtype of each column in a more compact form.
5. My DataFrame is huge — will head() be slow?
No, head() only pulls the first n rows from the underlying data structure; it's very fast even on millions of rows. info() is also efficient because it uses internal metadata, not a full scan of every cell (though it does count non-nulls, which may take a moment on very large data).
6. I used df.info(verbose=False) and now it's not printing the column list — why?
Like many pandas methods, info() accepts parameters. verbose=False suppresses the per-column output, giving you only the index, dtypes, and memory usage. Use it when you only need a quick summary.
What you learned & what's next
By now, you've mastered two of the most essential pandas techniques: using head() to preview rows and info() to summarize your DataFrame's structure. You've seen how they work together to give you a quick, reliable understanding of your data's contents, types, and missing values — saving you from costly mistakes later in your analysis. You also learned when to use these methods vs. alternatives like tail() and describe().
This knowledge directly supports your next step: data cleaning and type conversion. With head() and info() in your toolkit, you'll be able to identify issues like missing values, wrong dtypes, and problematic columns, and then fix them using methods like dropna(), fillna(), and astype(). That is the natural next topic in your data science journey — taking the raw, messy data you've inspected and turning it into a clean, analysis-ready dataset.
Practice recap
Now it's your turn: create your own DataFrame with at least one missing value and one numeric column, then call head() and info() on it. Observe how the dtype changes for columns with NaNs. Then, read a CSV file of your choice (or use pandas' built-in datasets like pd.read_csv(pd.utils.datasets.get_data_home() + '/iris.csv')) and apply the same inspection steps. You'll be surprised how much information you can gather in two commands.
Common mistakes
- Over-relying on head(): forgetting that the first rows might not represent the whole dataset, especially if it's sorted by a column like date.
- Ignoring the dtype column in info(): seeing 'object' for a numeric-looking column and not realizing it's actually text, or missing that an integer column became float64 due to NaNs.
- Only using head() or info() and not combining them: a quick preview without a structural summary means you miss missing values or unexpected dtypes.
Variations
- Use df.tail(n) to inspect the last n rows, useful for time-series data where recent entries matter.
- Use df.sample(n) for a random sample of rows, which can be more representative than head() when rows are ordered.
- Use df.describe() for a statistical summary of numeric columns, complementing the structural view from info().
Real-world use cases
- A data analyst receives a daily export of customer transactions and runs head() and info() to quickly check for missing order totals before building a revenue report.
- A machine learning engineer loads a training dataset and uses info() to spot columns with missing values and wrong dtypes, guiding cleaning steps before model training.
- A data scientist exploring a new dataset from a public source uses head() to see sample records and info() to understand column types, then decides whether to parse date columns with pd.to_datetime().
Key takeaways
- head() gives a quick visual preview of the first n rows (default 5), helping you eyeball column names and sample values.
- info() provides a structured summary of the DataFrame: columns, non-null counts, data types, and memory usage.
- Use head() first for a quick look, then info() for a structural health check — together they cover the 'what' and 'how' of your data.
- Watch for the dtype gotcha: missing values in integer columns cause pandas to convert them to float64.
- When head() may not be representative (e.g., sorted data), use sample() for a random peek.
- Mastering head() and info() is the foundation for effective data cleaning and type conversion, your next step.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.