Your dataset is clean. Every column is encoded. Every number is scaled. So you’re ready to build a model, right?
Not quite.
Cleaning and scaling make your data usable. They don’t make it understood. And that gap between usable and understood is exactly where models quietly fail. This guide walks you through exploratory data analysis in Python using a simple, repeatable framework — the same one covered in Episode 26 of the Intelevo Machine Learning series on YouTube. Watch the full video walkthrough here, or keep reading for the complete breakdown with code.
By the end, you’ll know how to look at any new dataset and immediately understand its shape, its gaps, and the relationships hiding inside it.
What Is Exploratory Data Analysis, Really?
Exploratory data analysis, or EDA, is a structured first pass through your data. You do it before a single model touches your dataset. Think of it as a reality check. It answers one core question: what am I actually working with?
Here’s why that question matters so much. Most “surprising” model failures aren’t surprising at all. They’re visible in the data from the very start. A column with a wild outlier. A distribution skewed so hard it breaks your assumptions. Two features that quietly measure the same thing. EDA catches every one of these issues before they cost you time, accuracy, or trust in your results.
So instead of jumping straight to model.fit(), you pause. You explore first. Then you model.
The Detective Analogy: A Simple Way to Think About EDA
Here’s a mental model that makes EDA click immediately: think like a detective walking into a scene for the first time.
A good detective never interrogates a suspect before looking around the room. In the same way, you never model a dataset before walking through it first. This one shift in mindset changes how you approach every new project.
Throughout this framework, you’ll follow four moves, just like a detective would:
- Survey the scene — get a first look at the dataset’s size and structure.
- Check for clues — hunt down missing values and odd entries.
- Profile the suspects — study how each column is shaped.
- Find the connections — uncover which columns move together.
Keep this analogy in mind as you go. It turns four abstract analytical steps into one intuitive story.
The Four-Question EDA Framework
Every EDA pass, regardless of the dataset, answers the same four questions in the same order:
| # | Question | What It Covers |
|---|---|---|
| 1 | What am I looking at? | Shape, columns, and data types |
| 2 | What’s missing or off? | Missing values, duplicates, bad entries |
| 3 | How is each column shaped? | Distributions and outliers |
| 4 | How do columns relate? | Correlations across the dataset |
These four questions expand into six practical steps. Let’s walk through each one, with code you can run right away.
Step 1: Survey the Scene — Your First Look
Before anything else, get the basic facts. How many rows and columns do you have? What type is each column? What do the actual rows look like?
Three lines of code answer all three questions:
import pandas as pd
df = pd.read_csv("shirts.csv")
print(df.shape)
# (5000, 7) → 5000 rows, 7 columns
df.info()
# column names, non-null counts, data types
df.head(5)
# a preview of the first 5 rows
df.shape gives you rows and columns instantly. df.info() lists every column alongside its data type and how many non-null values it holds. And df.head() shows real rows, not summary numbers, so you can eyeball whether the data actually looks the way you expect.
This step takes thirty seconds. Skip it, however, and you risk building an entire pipeline on a dataset you never actually looked at.
Step 2: Interview the Numbers — Summary Statistics
Next, get a statistical profile of every numeric column at once. One command handles it:
df.describe()
# price rating
# mean 1840 4.1
# std 910 0.6
# min 200 1.0
# 25% 1120 3.7
# 50% 1750 4.2
# 75% 2400 4.6
# max 5000 5.0
You don’t need a statistics degree to read this table. Focus on three signals instead.
First, compare the mean to the median (the 50% row). If they sit far apart, a few extreme values are pulling the average away from the typical row. Second, check the min and max. Does the range make real-world sense, or does something look off? Third, look at the standard deviation. It tells you how tightly values cluster around the mean, without requiring you to compute anything by hand.
Together, these three signals give you a fast, reliable snapshot of every numeric column.
Step 3: Look for Missing Clues
Real datasets have gaps. A sensor skips a reading. A customer leaves a field blank. Left unnoticed, these gaps either break your model outright or quietly bias its results.
Start by counting them:
df.isnull().sum()
# price 0
# rating 42
# size 310 ← worth a closer look
Once you know where the gaps are, you have two honest options. You can drop the affected rows:
df.dropna(subset=["rating"])
Or you can fill them thoughtfully:
df["size"].fillna(df["size"].mode()[0])
So which option should you choose? Here’s a simple rule of thumb: a handful of missing rows can usually just be dropped without consequence. But when an entire column is sparse, the why behind the gap matters more than which number you use to fill it. Investigate first, then decide.
Step 4: Profile the Shape of a Column
Numbers alone don’t always tell the full story. Shape does. A histogram shows how values spread out, and that shape alone often reveals a story without needing a single formula.
df["price"].hist(bins=30)
# or, for a smoother curve:
import seaborn as sns
sns.histplot(df["price"], kde=True)
Three shapes come up again and again, so learn to recognize them on sight:
- Symmetric — values cluster evenly around the middle. This is the easy, well-behaved case.
- Right-skewed — a long tail stretches toward high values. Price and income data often look this way.
- Left-skewed — a long tail stretches toward low values instead. It’s rarer, but it does happen.
Once you can recognize these shapes instantly, you’ll immediately know which columns need extra attention before modeling.
Step 5: Spot the Unusual Suspects — Outlier Detection
Now it’s time to hunt for outliers, the unusual suspects in your dataset. A boxplot visualizes the “normal range” of a column as a box, then marks anything outside it as a dot.
There’s exactly one formula worth memorizing in this entire framework:
IQR = Q3 − Q1
Q1 and Q3 are simply the 25th and 75th percentile marks. In fact, you already saw them in the describe() output from Step 2. From there, the outlier rule is straightforward: anything below Q1 − 1.5 × IQR, or above Q3 + 1.5 × IQR, counts as an outlier.
Q1 = df["price"].quantile(0.25)
Q3 = df["price"].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
outliers = df[(df["price"] < lower) | (df["price"] > upper)]
sns.boxplot(x=df["price"]) # see it visually
This single formula gives you a repeatable, defensible way to flag extreme values in any numeric column, every single time.
Step 6: Find the Connections — Correlation Analysis
The final step answers the fourth big question: how do columns relate to each other? Correlation measures how strongly two columns move together, and it always comes down to one number, ranging from −1 to +1.
- +1 means the two columns move perfectly together.
- 0 means there’s no relationship at all.
- −1 means they move in exactly opposite directions.
corr = df.corr(numeric_only=True)
sns.heatmap(corr, annot=True, cmap="coolwarm")
# rating vs. price → 0.61
# rating vs. return_rate → -0.74
# size vs. price → 0.03
df.corr() calculates this number for every pair of columns in one line. Then, sns.heatmap() turns that table into a color map you can scan in seconds. In the example above, rating and price move together fairly strongly, while rating and return rate move in nearly opposite directions. That’s the exact kind of pattern exploratory data analysis in Python is designed to surface.
Important Caution: Correlation Isn’t Causation
Before you draw any conclusions, remember this: two columns moving together doesn’t mean one causes the other.
Here’s the classic example. Ice cream sales and drowning incidents both rise every summer. Yet ice cream doesn’t cause drowning. Hot weather drives both trends independently. The correlation is real, but the causation isn’t.
So treat every correlation you find as a lead, not a verdict. It tells you where to look next, not what actually caused what. Ask yourself why two columns might move together before you build any conclusion on top of that number.
Putting It All Together: The Full EDA Workflow
Here’s the entire framework in one place:
- First Look —
shape,info(),head() - Summary Stats —
describe() - Missing Values —
isnull().sum() - Distributions — histograms and skew
- Outliers — the IQR rule
- Correlations —
corr()and heatmaps
These aren’t six separate projects. They’re six short passes through the same dataset. On most datasets, this entire walkthrough takes just a few minutes, and it pays for itself the very first time it catches a problem before your model does.
Where EDA Shows Up in the Real World
This framework isn’t just an academic exercise. Teams across industries rely on it daily.
In healthcare analytics, distributions of vital signs flag unusual readings before diagnostic models ever run. Also,in banking and credit, correlation checks catch redundant fields before they skew a risk score. In retail and e-commerce, outlier detection flags unusual orders, whether they turn out to be fraud, data errors, or genuine bulk buyers. And in cybersecurity, a spike outside the normal traffic distribution is often the very first clue that something has gone wrong.
Wherever data drives a decision, exploratory data analysis in Python comes first.
Quick Self-Check
Try this scenario before you move on. You plot a histogram of “delivery time” and notice a long tail stretching toward very large values, with most orders clustered on the low end. What are you looking at?
- A) A left-skewed distribution
- B) A right-skewed distribution, worth an IQR outlier check
- C) A perfectly symmetric distribution
The answer is B. A long tail of high values is the definition of right-skew, and that pattern is your cue to run an IQR check on that column.
What You Can Now Do
After working through this framework, you can confidently:
- Survey any dataset —
shape,info(), andhead()give you the geography in seconds. - Catch missing data early —
isnull().sum()surfaces gaps before they become model problems. - Read a distribution on sight — you can spot symmetric, skewed, and outlier-heavy columns without needing a formula.
- Find real relationships —
corr()and heatmaps reveal connections, and you know to treat them as leads, not verdicts.
That’s the complete loop. Six steps, one running analogy, and a dataset you now genuinely understand before a single model sees it.
Watch the Full Video Walkthrough
This article covers the written version of Episode 26 from the Intelevo Machine Learning series. For the full walkthrough, including live code demonstrations and visual explanations of every step above, watch the video on the Intelevo YouTube channel.
If this guide helped you, please like the video, subscribe to Intelevo, and share your thoughts in the comments below. Your feedback shapes what comes next in this series.
Coming Up Next: EP27 — Handling Imbalanced Datasets
You now know how to read a dataset honestly, outliers, skew, and all. But what happens when one outcome barely shows up in your data at all? In the next episode, we tackle class imbalance: why accuracy alone can lie to you, and how oversampling, undersampling, and SMOTE work together to even the odds.
See you in the next one.
