The idea
Correlation answers a narrow question: when one column is above its average, is the other column usually above its average too? It gives the answer as one number, r, between -1 and +1.
- Close to +1: they rise together. Pricier products have higher costs.
- Close to -1: one rises as the other falls.
- Close to 0: knowing one tells you little about the other, at least along a straight line.
That is all it says. It describes the pattern in the rows you have. It does not say why the pattern exists, whether it would hold if you changed one column on purpose, or whether it is big enough to matter.
Figure 1
Price and cost: when one is high, so is the other
| product_id | unit_price | unit_cost |
|---|---|---|
| 102 | 919.00 | 503.50 |
| 103 | 789.00 | 429.87 |
| 104 | 429.00 | 214.70 |
| 105 | 449.00 | 232.70 |
| 106 | 229.00 | 79.35 |
- Five Furniture products, two numeric columns. Correlation asks one question: when
unit_priceis above average, isunit_costabove average too? - Product 102 has the highest price and the highest cost. Product 106 has the lowest of both. The two columns rise and fall together.
- Across the 111 products that have a cost,
df[['unit_price', 'unit_cost']].corr()gives 0.98. Close to +1 means they move together almost in a straight line.
Why it exists
An analyst gets asked "does X go with Y?" all the time. Does more ad spend go with more orders?
Does a higher price go with fewer units sold? Do longer sessions go with more purchases? Reading
rows to find out does not work beyond a handful, and a scatter plot does not scale to 20 pairs. The
correlation number compresses a pair of columns into one comparable value, so corr() on a whole
DataFrame ranks every pair at once.
That is why the lesson belongs after the charts. A boxplot, a histogram and a regplot show you the data, and the correlation number summarises it; used together they catch each other's blind spots.
It is also where analysts most often claim too much. The number is so clean that it begs to be quoted as a cause. Learning what it supports, and what it does not, is the difference between a finding and an embarrassment in the next meeting, when someone asks 'but could it be the season?'.
How it works under the hood
From columns to one number
df.corr() standardises each column (how many standard deviations each value is from the column's
mean) and averages the products of the matching pairs. When both are above average together, or
below together, the products are positive and r goes up. When one is high while the other is low,
the products are negative. The result is a matrix: every numeric column against every other, with 1.0 on
the diagonal because a column perfectly matches itself.
A seaborn heatmap, sns.heatmap(df.corr(), annot=True), paints that matrix so the strong cells
stand out. Read it by scanning for the dark cells off the diagonal. The matrix is symmetric, so every
pair shows up twice, and "the strongest pairs" means looking at one triangle. A good habit is to
sort the pairs by absolute value, because -0.9 is as strong as +0.9.
What r does not measure
r measures straight-line togetherness. A relationship that rises and then falls can have an r
near 0 and still be perfectly clear on a chart. That is why you draw the scatter plot (sns.regplot)
as well: the number tells you how strong, the picture tells you what shape.
It is also sensitive to outliers. One extreme point can pull r up or down, because the extreme value contributes a large product. Find outliers first, with the IQR rule or a boxplot, then decide whether the point belongs in the story.
Why a strong r can still mislead
Take 2025 by month. Ad spend and orders have r = 0.95.
There are at least three explanations for a number like that. Spend may cause orders. Orders may cause spend, for example a budget that follows revenue. Or something else, here the holiday season, may raise both. The correlation is the same in all three. To tell them apart you need an experiment (change spend in some regions and not others), a comparison that holds the season fixed, or knowledge of how the budget was set.
The slope helps with size. A line through the 12 points rises by about 14 orders for every extra $1,000 of monthly spend. That is a description of the months in the data. Extending it to a doubled budget goes beyond the data you have.
Writing the conclusion
Analysis that stops at the number is unfinished. A manager needs a sentence they can act on, and the sentence has a shape.
Figure 3
A takeaway has four parts
- Finding what the numbers show
- Size how big, in units the reader knows
- So what what to do or check next
- Limit what the data cannot say
- Say what you found, in one sentence a manager can repeat: 'Months with more ad spend had more orders in 2025.'
- Say how big, computed and not guessed: correlation 0.95, about 14 extra orders per extra $1,000 of monthly spend.
- Say what follows from it: test a spend change in a quiet month before assuming the relationship holds.
- Say what the data cannot show: November and December raise both, so this is not proof that spend causes orders.
Every number in it should be computed from your data, not estimated by eye. The limit is part of the finding: it tells the reader how far to trust it, and it protects you when someone quotes your sentence without the context.
Common misconceptions
"A correlation of 0.95 means ad spend causes 95% of orders"
r is not a percentage of anything. Squared, it is the share of the variation in one column that a straight line on the other describes, about 91% here, and that is still a statement about patterns in the rows. Cause needs separate evidence: an experiment, or a reason the other explanations fail.
"If r is near zero, the columns are unrelated"
It means no straight-line relationship. A U-shaped one can hide behind r = 0. Always look at the scatter plot before you say "no relationship", and check whether one group of rows cancels another, such as consumers against business customers.
"A strong correlation in the totals will hold in every group"
Correlations can change sign when you split the data. Two columns can move together across the
whole store and move apart inside each category or segment, because the groups sit at different
levels. If a pair matters to a decision, recompute it per group (groupby then corr) before you
write the takeaway.
Check yourself
One question. Answering it ticks this lesson off on the map; it never locks a level.
Not quite. A correlation describes what happened, not what would happen if you changed one column. November and December raise both, and the number cannot separate that from a real effect of spend.Try another answer.
Not quite. 0.95 is not a share of orders. Squaring it gives about 0.91, the share of the variation in one column that a straight line on the other accounts for, and even that says nothing about cause.Try another answer.
Right. This is what the number says: the two columns move together across months. It stops there.
Not quite. A correlation measures exactly how strongly two columns move together in a straight line. 0.95 is a strong one.Try another answer.
Lesson done: it is ticked on the map.