Exploratory data analysis in Python

Exploratory Data Analysis in Python: The Complete Beginner’s Framework

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:

  1. Survey the scene — get a first look at the dataset’s size and structure.
  2. Check for clues — hunt down missing values and odd entries.
  3. Profile the suspects — study how each column is shaped.
  4. 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:

#QuestionWhat It Covers
1What am I looking at?Shape, columns, and data types
2What’s missing or off?Missing values, duplicates, bad entries
3How is each column shaped?Distributions and outliers
4How 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:

  1. First Lookshape, info(), head()
  2. Summary Statsdescribe()
  3. Missing Valuesisnull().sum()
  4. Distributions — histograms and skew
  5. Outliers — the IQR rule
  6. Correlationscorr() 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 datasetshape, info(), and head() give you the geography in seconds.
  • Catch missing data earlyisnull().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 relationshipscorr() 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.

Leave a Comment

Your email address will not be published. Required fields are marked *