Foundations of Data Science 📂 Descriptive Statistics · 4 of 11 96 min read

Quartiles, IQR and Outlier Detection

Learn what quartiles and the Interquartile Range (IQR) are, how to calculate them step by step, and how to use the IQR method to detect and handle outliers in your data — with real stories and Python code.

🌐
SectionSection第 01 节

The Story That Explains Everythingवह कहानी जो सब कुछ समझाती है一个讲清一切的故事

You are an HR analyst at a tech company. The CEO asks you for the "typical" salary. You pull the data for 12 employees:

आप एक tech company में HR analyst हैं। CEO आपसे "आम" salary पूछते हैं। आप 12 कर्मचारियों का data निकालते हैं:

你是一家科技公司的 HR 分析师。CEO 让你报告“典型”工资。你调出了 12 名员工的数据:

Employeeकर्मचारी员工RoleRole职位Salary (£)Salary (£)工资(£)
1Junior DeveloperJunior Developer初级开发32,000
2Junior DeveloperJunior Developer初级开发34,000
3Junior DeveloperJunior Developer初级开发33,000
4Mid DeveloperMid Developer中级开发48,000
5Mid DeveloperMid Developer中级开发51,000
6Mid DeveloperMid Developer中级开发49,000
7Senior DeveloperSenior Developer高级开发72,000
8Senior DeveloperSenior Developer高级开发75,000
9Senior DeveloperSenior Developer高级开发78,000
10Lead DeveloperLead Developer开发组长95,000
11Engineering ManagerEngineering Manager工程经理120,000
12CTOCTO首席技术官(CTO)380,000

The mean salary is £88,917. You report this to the CEO. Every junior developer in the room is confused — they earn about £33,000, and the "average" is £88,917? The CTO's £380,000 has dragged the mean above what 9 of the 12 employees earn.

Mean salary £88,917 है। आप यही CEO को बताते हैं। कमरे में हर junior developer उलझन में है — वे लगभग £33,000 कमाते हैं, और "average" £88,917? CTO के £380,000 ने mean को 12 में से 9 कर्मचारियों की कमाई से ऊपर खींच दिया है।

平均工资是 £88,917。你把这个数报给了 CEO。会议室里每位初级开发都很困惑 —— 他们只挣约 £33,000,“平均”却是 £88,917? CTO 的 £380,000 把均值拉到了 12 人中 9 人的工资之上。

⚠️
The Problem with the Mean and OutliersMean और Outliers की समस्या均值与离群点的问题

The CTO's salary is an outlier — a value so extreme that it distorts the mean. That is why data scientists never rely on the mean alone. Quartiles and the IQR give a far more honest picture of where the middle of the data sits — and they give a simple rule to flag unusual values.

CTO की salary एक outlier है — इतनी extreme value कि mean को बिगाड़ देती है। इसीलिए data scientists सिर्फ़ mean पर भरोसा नहीं करते। Quartiles और IQR बताते हैं कि data का बीच असल में कहाँ है — और असामान्य values पकड़ने का एक आसान नियम देते हैं।

CTO 的工资是一个离群点 —— 一个极端到足以扭曲均值的值。所以数据科学家从不只看均值。四分位数和 IQR 能更诚实地告诉你数据的中间在哪里 —— 还提供了一条标记异常值的简单规则。


SectionSection第 02 节

What Are Quartiles?Quartiles क्या हैं?什么是四分位数?

Quartiles split a sorted dataset into four parts, each holding about 25% of the values. There are three quartile values:

Quartiles एक sort किए dataset को चार हिस्सों में बाँटते हैं, हर हिस्से में लगभग 25% values. तीन quartile values होती हैं:

四分位数把排好序的数据分成四份,每份约含 25% 的数值。共有三个四分位数:

🏃 QUARTILES AS A RACERACE के रूप में QUARTILES把四分位数想象成一场赛跑
Quartiles as a race fastest 25%सबसे तेज़ 25%最快的 25% next 25%अगले 25%接下来的 25% next 25%अगले 25%再接下来的 25% slowest 25%सबसे धीमे 25%最慢的 25% Q1 Q2 Q3 Runners sorted by finishing time → Q1, Q2 (median) and Q3 split them into four equal groups.Finish time के क्रम में runners → Q1, Q2 (median) और Q3 उन्हें चार बराबर groups में बाँटते हैं।选手按完赛时间排好 → Q1、Q2(中位数)和 Q3 把他们分成四个人数相等的组。
Q1Q1Q1
25th percentile25th percentile第 25 百分位数
  • Lower quartileLower quartile下四分位数
  • About 25% of data belowलगभग 25% data नीचे约 25% 的数据在它下面
  • About 75% of data aboveलगभग 75% data ऊपर约 75% 的数据在它上面
Q2Q2Q2
50th percentile50th percentile第 50 百分位数
  • The medianMedian就是中位数
  • 50% of data below50% data नीचे50% 的数据在它下面
  • 50% of data above50% data ऊपर50% 的数据在它上面
Q3Q3Q3
75th percentile75th percentile第 75 百分位数
  • Upper quartileUpper quartile上四分位数
  • About 75% of data belowलगभग 75% data नीचे约 75% 的数据在它下面
  • About 25% of data aboveलगभग 25% data ऊपर约 25% 的数据在它上面
💡
Think of It Like a Raceइसे एक Race की तरह सोचें把它想象成一场赛跑

Imagine 100 runners finishing a race. Q1 is roughly the time of runner 25 — the fastest quarter is home. Q2 is runner 50 — half are done. Q3 is runner 75. The runners between Q1 and Q3 are the middle 50% — the core of the pack. Stragglers far behind Q3, or sprinters far ahead of Q1, are candidates for outliers.

100 runners की race की कल्पना करें। Q1 लगभग 25वें runner का समय है — सबसे तेज़ चौथाई पहुँच चुकी। Q2 50वाँ runner है — आधे पहुँच गए। Q3 75वाँ runner है। Q1 और Q3 के बीच के runners बीच के 50% हैं — भीड़ का मुख्य हिस्सा। Q3 से बहुत पीछे वाले, या Q1 से बहुत आगे वाले, outliers हो सकते हैं।

想象 100 名选手跑完一场比赛。Q1 大约是第 25 名的成绩 —— 最快的四分之一已经到达;Q2 是第 50 名 —— 一半人到了;Q3 是第 75 名。Q1 和 Q3 之间的选手就是中间的 50% —— 大部队的核心。 远远落在 Q3 后面的掉队者,或远远领先 Q1 的冲刺者,都可能是离群点。

LIVELIVE互动Find Q1, Q2 and Q3 on Sorted CardsSort किए Cards पर Q1, Q2 और Q3 खोजें在排好序的卡片上找 Q1、Q2、Q3

Cards are sorted and coloured by quarter. Try an odd and an even list, add a huge value, and switch between the hand method and NumPy's default — they can give slightly different quartiles.

Cards sort किए गए हैं और चौथाई के हिसाब से रंगे हैं। Odd और even list आज़माएँ, एक बहुत बड़ी value जोड़ें, और हाथ वाले तरीके व NumPy के default के बीच बदलें — दोनों थोड़े अलग quartiles दे सकते हैं।

卡片已排序,并按四分之一着色。试试奇数和偶数个的列表,加入一个超大值,再在手算方法和 NumPy 默认方法之间切换 —— 它们给出的四分位数可能略有不同。


SectionSection第 03 节

What Is the IQR?IQR क्या है?什么是 IQR?

The Interquartile Range (IQR) is the distance between Q1 and Q3. It covers the middle 50% of the data — the typical range — and ignores the extreme low and high values.

Interquartile Range (IQR) Q1 और Q3 के बीच की दूरी है। यह data के बीच के 50% को cover करता है — आम range — और बहुत नीची व बहुत ऊँची values को अनदेखा करता है।

四分位距(IQR)是 Q1 到 Q3 的距离。它涵盖数据中间的 50% —— 典型范围 —— 并忽略极低和极高的值。

Interquartile RangeInterquartile Range四分位距
IQR = Q3 − Q1
The spread of the middle 50% of the data. Extreme values at either end barely move it.
Data के बीच के 50% का फैलाव। दोनों सिरों की extreme values इसे मुश्किल से हिलाती हैं।
中间 50% 数据的离散程度。两端的极端值几乎撼动不了它。
📦 ANATOMY OF A BOX PLOT (THE SALARY DATA)BOX PLOT की बनावट (SALARY DATA)箱线图的结构(工资数据)
Anatomy of a box plot whiskerwhisker须线 Q1 median (Q2)median (Q2)中位数(Q2) Q3 whiskerwhisker须线 upper fence = Q3 + 1.5 × IQRupper fence = Q3 + 1.5 × IQR上围栏 = Q3 + 1.5 × IQR outlier (CTO)outlier (CTO)离群点(CTO) box = IQR = middle 50%box = IQR = बीच का 50%箱体 = IQR = 中间 50% £0k £50k £100k £150k £200k £250k £300k £350k £400k

The whiskers stretch to the lowest and highest values that are still inside the fences (£32k and £120k). Anything beyond a fence is drawn as a separate point.

Whiskers fences के अंदर की सबसे छोटी और सबसे बड़ी values (£32k और £120k) तक जाते हैं। Fence से बाहर की हर चीज़ अलग point के रूप में बनती है।

须线延伸到仍在围栏之内的最小值和最大值(£32k 和 £120k)。超出围栏的值单独画成一个点。

📐
Why the IQR Beats the RangeIQR, Range से बेहतर क्यों है为什么 IQR 比极差好

The full range (max − min) is ruined by one outlier: here it is £380,000 − £32,000 = £348,000, almost all of it caused by the CTO. The IQR ignores both ends and shows the spread of the middle majority: £45,500 with the hand method.

पूरी range (max − min) एक outlier से बिगड़ जाती है: यहाँ यह £380,000 − £32,000 = £348,000 है, जिसका लगभग सारा हिस्सा CTO की वजह से है। IQR दोनों सिरों को अनदेखा करके बीच के बहुमत का फैलाव दिखाता है: हाथ वाले तरीके से £45,500.

极差(最大值 − 最小值)会被一个离群点彻底破坏:这里是 £380,000 − £32,000 = £348,000,几乎全由 CTO 造成。IQR 忽略两端,展示中间大多数人的离散程度:手算方法得到 £45,500。


SectionSection第 04 节

Step-by-Step CalculationStep-by-Step गणना分步计算

Let us use a simpler dataset first: [4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45]

पहले एक आसान dataset लें: [4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45]

先用一个简单的数据集:[4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45]

🧮 Finding Q1, Q2, Q3 and IQR (hand method)Q1, Q2, Q3 और IQR खोजना (हाथ वाला तरीका)求 Q1、Q2、Q3 和 IQR(手算方法)
Step 1
Sort the data (already sorted).
[4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45] — n = 12 values
Data sort करें (पहले से sorted)।
[4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45] — n = 12 values
排序(已经排好)。
[4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45] —— n = 12
Step 2
Find Q2 (median) — average of the 6th and 7th values: (18 + 21) / 2 = 19.5
Q2 (median) खोजें — 6वीं और 7वीं value का औसत: (18 + 21) / 2 = 19.5
求 Q2(中位数)—— 第 6 和第 7 个值的平均:(18 + 21) / 2 = 19.5
Step 3
Find Q1 — median of the lower half [4, 7, 9, 12, 15, 18]: (9 + 12) / 2 = 10.5
Q1 खोजें — निचले आधे [4, 7, 9, 12, 15, 18] का median: (9 + 12) / 2 = 10.5
求 Q1 —— 下半部分 [4, 7, 9, 12, 15, 18] 的中位数:(9 + 12) / 2 = 10.5
Step 4
Find Q3 — median of the upper half [21, 24, 28, 35, 38, 45]: (28 + 35) / 2 = 31.5
Q3 खोजें — ऊपरी आधे [21, 24, 28, 35, 38, 45] का median: (28 + 35) / 2 = 31.5
求 Q3 —— 上半部分 [21, 24, 28, 35, 38, 45] 的中位数:(28 + 35) / 2 = 31.5
Step 5
IQR = Q3 − Q1 = 31.5 − 10.5 = 21.0
IQR = Q3 − Q1 = 31.5 − 10.5 = 21.0
IQR = Q3 − Q1 = 31.5 − 10.5 = 21.0
ℹ️
Odd Number of Values?Values की संख्या Odd हो तो?数值个数是奇数怎么办?

With an odd n, the median is a single value. In this hand method it is left out of both halves (for example, with 11 values the halves are values 1–5 and 7–11). Some textbooks include it instead — another reason why different tools can give slightly different quartiles.

Odd n में median एक अकेली value होती है। इस हाथ वाले तरीके में उसे दोनों आधों से बाहर रखा जाता है (जैसे 11 values में आधे हिस्से values 1–5 और 7–11 हैं)। कुछ किताबें उसे शामिल करती हैं — यह भी एक वजह है कि अलग tools थोड़े अलग quartiles देते हैं।

n 为奇数时,中位数是单独一个值。在这种手算方法中,它不放入任何一半(比如 11 个值时,两半分别是第 1–5 个和第 7–11 个)。也有教材会把它放进去 —— 这也是不同工具给出的四分位数略有差异的原因之一。


SectionSection第 05 节

How to Detect Outliers Using the IQRIQR से Outliers कैसे पकड़ें如何用 IQR 检测离群点

The IQR method uses fences — boundaries beyond which a value is flagged as an outlier. Box plots use exactly this rule.

IQR तरीका fences इस्तेमाल करता है — ऐसी सीमाएँ जिनके बाहर की value outlier मानी जाती है। Box plots ठीक यही नियम इस्तेमाल करते हैं।

IQR 方法使用围栏(fences) —— 超出这些边界的值被标记为离群点。箱线图用的正是这条规则。

Lower FenceLower Fence下围栏
Q1 − 1.5 × IQR
Any value below this is a lower outlier.
इससे नीचे की हर value lower outlier है।
低于它的值是下离群点。
Upper FenceUpper Fence上围栏
Q3 + 1.5 × IQR
Any value above this is an upper outlier.
इससे ऊपर की हर value upper outlier है।
高于它的值是上离群点。
💡
Why 1.5?1.5 क्यों?为什么是 1.5?

The 1.5 multiplier comes from John Tukey's 1977 book Exploratory Data Analysis. It is a practical choice, not a law of nature. For normally distributed data the fences fall at about ±2.7 standard deviations, so only about 0.7% of values land outside them by chance. Some analyses use 3 × IQR to flag only "extreme" outliers.

1.5 का multiplier John Tukey की 1977 की किताब Exploratory Data Analysis से आता है। यह एक व्यावहारिक चुनाव है, प्रकृति का नियम नहीं। Normal data के लिए fences लगभग ±2.7 standard deviations पर होते हैं, इसलिए संयोग से सिर्फ़ लगभग 0.7% values बाहर जाती हैं। कुछ analyses सिर्फ़ "extreme" outliers के लिए 3 × IQR इस्तेमाल करते हैं।

1.5 这个倍数来自 John Tukey 1977 年的著作《探索性数据分析》。它是一个实用的选择,而不是自然规律。对正态数据,围栏大约位于 ±2.7 个标准差处,所以只有约 0.7% 的值会因偶然落在外面。有些分析用 3 × IQR 来只标记“极端”离群点。

Applying the fences to the salary dataSalary data पर fences लगाना把围栏用到工资数据上

🧮 Outlier Detection — Salary Data (hand method)Outlier Detection — Salary Data (हाथ वाला तरीका)离群点检测 —— 工资数据(手算方法)
Data
Sorted salaries (£000s): [32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380]
Sort की गई salaries (£000s): [32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380]
排序后的工资(£ 千):[32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380]
Q1
Lower half [32, 33, 34, 48, 49, 51] → Q1 = (34 + 48) / 2 = 41
निचला आधा [32, 33, 34, 48, 49, 51] → Q1 = (34 + 48) / 2 = 41
下半部分 [32, 33, 34, 48, 49, 51] → Q1 = (34 + 48) / 2 = 41
Q3
Upper half [72, 75, 78, 95, 120, 380] → Q3 = (78 + 95) / 2 = 86.5
ऊपरी आधा [72, 75, 78, 95, 120, 380] → Q3 = (78 + 95) / 2 = 86.5
上半部分 [72, 75, 78, 95, 120, 380] → Q3 = (78 + 95) / 2 = 86.5
IQR
IQR = 86.5 − 41 = 45.5
IQR = 86.5 − 41 = 45.5
IQR = 86.5 − 41 = 45.5
Fences
Lower fence = 41 − 1.5 × 45.5 = −27.25 (no lower outliers possible)
Upper fence = 86.5 + 1.5 × 45.5 = 154.75
Lower fence = 41 − 1.5 × 45.5 = −27.25 (कोई lower outlier संभव नहीं)
Upper fence = 86.5 + 1.5 × 45.5 = 154.75
下围栏 = 41 − 1.5 × 45.5 = −27.25(不可能有下离群点)
上围栏 = 86.5 + 1.5 × 45.5 = 154.75
Result
Any salary above £154,750 is an outlier.
£380,000 (CTO) > £154,750 → OUTLIER
£120,000 (Engineering Manager) < £154,750 → normal
£154,750 से ऊपर की हर salary outlier है।
£380,000 (CTO) > £154,750 → OUTLIER
£120,000 (Engineering Manager) < £154,750 → normal
高于 £154,750 的工资都是离群点。
£380,000(CTO)> £154,750 → 离群点
£120,000(工程经理)< £154,750 → 正常
✅
Resultनतीजा结果

The IQR method confirms what we suspected — the CTO's £380,000 is a statistical outlier. The median salary is £61,500. That is the honest "typical" salary to report — not the mean of £88,917, which the outlier pushed up by about £27,400.

IQR तरीका वही पक्का करता है जिसका शक था — CTO की £380,000 एक statistical outlier है। Median salary £61,500 है। यही ईमानदार "आम" salary है जो बतानी चाहिए — £88,917 वाला mean नहीं, जिसे outlier ने लगभग £27,400 ऊपर धकेल दिया।

IQR 方法证实了我们的怀疑 —— CTO 的 £380,000 是统计意义上的离群点。工资中位数是 £61,500,这才是应该报告的诚实的“典型”工资 —— 而不是被离群点推高了约 £27,400 的均值 £88,917。

LIVELIVE互动Build a Box Plot — Drag the SalariesBox Plot बनाएँ — Salaries खींचें动手做箱线图 — 拖动工资

The 12 salaries (£k) are the dots at the bottom; the box plot above updates live (hand method). Drag the CTO back into the crowd, drag someone far away, or change the fence multiplier from 1.5 to 3.

12 salaries (£k) नीचे के dots हैं; ऊपर का box plot live update होता है (हाथ वाला तरीका)। CTO को भीड़ में वापस खींचें, किसी को बहुत दूर ले जाएँ, या fence multiplier को 1.5 से 3 करें।

下方的点是 12 个工资(£k),上方的箱线图实时更新(手算方法)。把 CTO 拖回人群,把某人拖得很远,或把围栏倍数从 1.5 改成 3。


SectionSection第 06 节

Python ImplementationPython ImplementationPython 实现

Manual calculation (hand method)हाथ से गणना (हाथ वाला तरीका)手动计算(手算方法)

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

salaries_sorted = sorted(salaries)
n = len(salaries_sorted)

# Q2 — median
mid = n // 2
q2 = (salaries_sorted[mid - 1] + salaries_sorted[mid]) / 2

# Q1 — median of lower half
lower_half = salaries_sorted[:mid]
q1 = (lower_half[len(lower_half)//2 - 1] + lower_half[len(lower_half)//2]) / 2

# Q3 — median of upper half
upper_half = salaries_sorted[mid:]
q3 = (upper_half[len(upper_half)//2 - 1] + upper_half[len(upper_half)//2]) / 2

iqr = q3 - q1

lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr

print(f"Q1: £{q1:,.0f}")
print(f"Q2: £{q2:,.0f}")
print(f"Q3: £{q3:,.0f}")
print(f"IQR: £{iqr:,.0f}")
print(f"Lower fence: £{lower_fence:,.0f}")
print(f"Upper fence: £{upper_fence:,.0f}")

outliers = [s for s in salaries if s < lower_fence or s > upper_fence]
print(f"Outliers: {outliers}")
OUTPUT
Q1: £41,000 Q2: £61,500 Q3: £86,500 IQR: £45,500 Lower fence: £-27,250 Upper fence: £154,750 Outliers: [380000]

Using NumPyNumPy से使用 NumPy

import numpy as np

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

q1  = np.percentile(salaries, 25)
q2  = np.percentile(salaries, 50)
q3  = np.percentile(salaries, 75)
iqr = q3 - q1

lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr

salaries_arr = np.array(salaries)
outliers = salaries_arr[(salaries_arr < lower_fence) | (salaries_arr > upper_fence)]

print(f"Q1:  £{q1:,.0f}")
print(f"Q2:  £{q2:,.0f}")
print(f"Q3:  £{q3:,.0f}")
print(f"IQR: £{iqr:,.0f}")
print(f"Upper fence: £{upper_fence:,.0f}")
print(f"Outliers: {outliers}")

# Why are these different from the hand calculation (41,000 and 86,500)?
# NumPy's default method interpolates between data points ("linear").
# Other textbook methods give other answers — none of them is "wrong":
for m in ["linear", "midpoint", "lower", "higher"]:
    a, b = np.percentile(salaries, [25, 75], method=m)
    print(f"method={m:9s} Q1 = £{a:,.0f}   Q3 = £{b:,.0f}")
OUTPUT
Q1: £44,500 Q2: £61,500 Q3: £82,250 IQR: £37,750 Upper fence: £138,875 Outliers: [380000] method=linear Q1 = £44,500 Q3 = £82,250 method=midpoint Q1 = £41,000 Q3 = £86,500 method=lower Q1 = £34,000 Q3 = £78,000 method=higher Q1 = £48,000 Q3 = £95,000
⚠️
Why NumPy Gives Different QuartilesNumPy अलग Quartiles क्यों देता है为什么 NumPy 算出的四分位数不一样

NumPy's default (method="linear") does not split the data into halves. It places Q1 at position (n − 1) × 0.25 and interpolates between neighbours, so it gives Q1 = £44,500 and Q3 = £82,250 — not £41,000 and £86,500. pandas .quantile() uses the same default. Neither answer is wrong; there are several accepted definitions. With small datasets the difference is noticeable, with large datasets it almost disappears. Just use one method consistently — and say which one.

NumPy का default (method="linear") data को आधे हिस्सों में नहीं बाँटता। यह Q1 को position (n − 1) × 0.25 पर रखता है और पड़ोसियों के बीच interpolate करता है, इसलिए Q1 = £44,500 और Q3 = £82,250 देता है — £41,000 और £86,500 नहीं। pandas .quantile() भी यही default इस्तेमाल करता है। कोई भी जवाब ग़लत नहीं; कई मान्य परिभाषाएँ हैं। छोटे datasets में अंतर दिखता है, बड़े में लगभग ग़ायब हो जाता है। बस एक तरीका लगातार इस्तेमाल करें — और बताएँ कि कौन सा।

NumPy 的默认方法(method="linear")不会把数据对半分。它把 Q1 放在位置 (n − 1) × 0.25,并在相邻值之间插值,所以得到 Q1 = £44,500、Q3 = £82,250 —— 而不是 £41,000 和 £86,500。pandas 的 .quantile() 默认也一样。 两个答案都没错;四分位数有好几种公认的定义。小数据集上差别明显,大数据集上几乎消失。只要始终使用同一种方法 —— 并说明用的是哪一种。

Using pandaspandas से使用 pandas

import pandas as pd

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

df = pd.DataFrame({"salary": salaries})

q1  = df["salary"].quantile(0.25)
q3  = df["salary"].quantile(0.75)
iqr = q3 - q1

lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr

# Flag outliers as a new column
df["is_outlier"] = (df["salary"] < lower_fence) | (df["salary"] > upper_fence)

print(df)
print(f"\nOutlier rows:")
print(df[df["is_outlier"]])
OUTPUT
salary is_outlier 0 32000 False 1 33000 False 2 34000 False 3 48000 False 4 49000 False 5 51000 False 6 72000 False 7 75000 False 8 78000 False 9 95000 False 10 120000 False 11 380000 True Outlier rows: salary is_outlier 11 380000 True

Visualising with a box plotBox plot से दिखाना用箱线图可视化

import matplotlib.pyplot as plt
import numpy as np

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# Box plot — outliers shown as circles beyond the whiskers
axes[0].boxplot(salaries, vert=True, patch_artist=True,
                boxprops=dict(facecolor="#3776AB", alpha=0.6))
axes[0].set_title("Salary Box Plot")
axes[0].set_ylabel("Salary (£)")
axes[0].yaxis.set_major_formatter(
    plt.FuncFormatter(lambda x, _: f"£{x:,.0f}")
)

# Same data without outlier for comparison
salaries_clean = [s for s in salaries if s <= 154750]
axes[1].boxplot(salaries_clean, vert=True, patch_artist=True,
                boxprops=dict(facecolor="#34d399", alpha=0.6))
axes[1].set_title("Salaries Without Outlier")
axes[1].set_ylabel("Salary (£)")
axes[1].yaxis.set_major_formatter(
    plt.FuncFormatter(lambda x, _: f"£{x:,.0f}")
)

plt.suptitle("IQR Outlier Detection — Box Plots", fontsize=13)
plt.tight_layout()
plt.show()

This draws two box plots side by side. Matplotlib uses the same 1.5 × IQR rule for the whiskers (whis=1.5) and shows points beyond them as circles.

यह दो box plots साथ-साथ बनाता है। Matplotlib whiskers के लिए वही 1.5 × IQR नियम (whis=1.5) इस्तेमाल करता है और उनसे बाहर के points को गोलों के रूप में दिखाता है।

这段代码并排画出两个箱线图。Matplotlib 的须线使用同样的 1.5 × IQR 规则(whis=1.5),超出的点以圆圈显示。


SectionSection第 07 节

What to Do When You Find OutliersOutliers मिलें तो क्या करें发现离群点后该怎么办

Finding an outlier is only the first step. What you do next depends on why it exists:

Outlier मिलना सिर्फ़ पहला कदम है। आगे क्या करना है, यह इस पर निर्भर है कि वह क्यों है:

发现离群点只是第一步。接下来怎么做,取决于它为什么存在:

Reasonवजह原因Exampleउदाहरण例子Actionक्या करें处理方式
Data entry errorData entry की ग़लती录入错误Height typed as 1700 cm instead of 170 cmHeight 170 cm की जगह 1700 cm लिखी गई身高把 170 cm 录成了 1700 cmFix or removeठीक करें या हटाएँ更正或删除
Measurement errorMeasurement की ग़लती测量错误A faulty sensor reports 0 °C on a summer dayख़राब sensor गर्मी के दिन 0 °C बताता है故障传感器在夏天报告 0 °CRemove (or replace)हटाएँ (या बदलें)删除(或替换)
Legitimate extreme valueअसली extreme value真实的极端值The CTO really earns £380,000CTO सच में £380,000 कमाता हैCTO 确实挣 £380,000Keep — report separately or use robust statisticsरखें — अलग बताएँ या robust statistics इस्तेमाल करें保留 —— 单独报告或使用稳健统计量
Interesting anomalyदिलचस्प anomaly有价值的异常A fraudulent transactionएक fraudulent transaction一笔欺诈交易Keep — it is the signalरखें — यही असली संकेत है保留 —— 它就是信号
⚠️
Never Blindly Remove OutliersOutliers को कभी आँख मूँदकर न हटाएँ永远不要盲目删除离群点

Removing outliers without understanding them is one of the most dangerous mistakes in data science. In fraud detection the outliers are what you are looking for. In medical research, removing extreme readings could hide an important finding. Investigate first — then decide.

बिना समझे outliers हटाना data science की सबसे ख़तरनाक ग़लतियों में से एक है। Fraud detection में outliers ही वह चीज़ हैं जो आप खोज रहे हैं। Medical research में extreme readings हटाने से कोई ज़रूरी खोज छिप सकती है। पहले जाँच करें — फिर फ़ैसला करें।

不理解就删除离群点,是数据科学中最危险的错误之一。在欺诈检测中,离群点正是你要找的东西。在医学研究中,删掉极端读数可能会掩盖重要发现。先调查 —— 再决定。

Remove, cap, or use the medianहटाएँ, cap करें, या median इस्तेमाल करें删除、截断,还是用中位数

import numpy as np

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

q1  = np.percentile(salaries, 25)
q3  = np.percentile(salaries, 75)
iqr = q3 - q1

lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr

# Option 1 — Remove outliers
clean = [s for s in salaries if lower_fence <= s <= upper_fence]
print(f"After removal: {len(clean)} values, mean = £{sum(clean)/len(clean):,.0f}")

# Option 2 — Cap outliers (Winsorisation)
# Replace outlier with the fence value instead of removing
capped = [max(lower_fence, min(upper_fence, s)) for s in salaries]
print(f"After capping: mean = £{sum(capped)/len(capped):,.0f}")

# Option 3 — Use median (unaffected by outliers)
median = np.median(salaries)
print(f"Median (no action needed): £{median:,.0f}")
OUTPUT
After removal: 11 values, mean = £62,455 After capping: mean = £68,823 Median (no action needed): £61,500

Capping (also called winsorising) replaces the CTO's £380,000 with the upper fence (£138,875 with NumPy's quartiles), so the row stays in the data but can no longer dominate the mean.

Capping (जिसे winsorising भी कहते हैं) CTO के £380,000 को upper fence (NumPy के quartiles से £138,875) से बदल देता है, ताकि row data में रहे पर mean पर हावी न हो सके।

截断(也叫缩尾,winsorising)把 CTO 的 £380,000 替换成上围栏(用 NumPy 四分位数时为 £138,875),这一行留在数据里,却再也无法主导均值。


SectionSection第 08 节

IQR vs Z-Score — Two Methods ComparedIQR vs Z-Score — दो तरीकों की तुलनाIQR vs Z 分数 — 两种方法对比

Propertyगुण特性IQR methodIQR तरीकाIQR 方法Z-score methodZ-score तरीकाZ 分数方法
FormulaFormula公式Q1 − 1.5×IQR, Q3 + 1.5×IQRz = (x − mean) / SD
ThresholdThreshold阈值Beyond the fencesFences से बाहर超出围栏|z| > 3 (sometimes 2)(कभी-कभी 2)(有时用 2)
Pulled by the outliers themselves?ख़ुद outliers से खिंचता है?会被离群点本身拉偏吗?Hardlyमुश्किल से几乎不会Yes — mean and SD both moveहाँ — mean और SD दोनों हिलते हैं会 —— 均值和标准差都会变
Best forसबसे अच्छा最适合Unknown or moderately skewed shapeअज्ञात या थोड़ा skewed आकार分布未知或中度偏斜Roughly normal data, larger samplesलगभग normal data, बड़े samples近似正态、样本较大
Weak spotकमज़ोरी弱点Flags many real values in long-tailed dataलंबी पूँछ वाले data में बहुत सी असली values पकड़ता है在长尾数据中会标记大量真实值Masking: a big outlier inflates the SD and hides itselfMasking: बड़ा outlier SD बढ़ाकर ख़ुद को छिपा लेता है掩蔽效应:大离群点撑大标准差,把自己藏起来
import numpy as np

salaries = [32000, 33000, 34000, 48000, 49000, 51000,
            72000, 75000, 78000, 95000, 120000, 380000]

# ── IQR Method ──────────────────────────────────────────────
q1, q3  = np.percentile(salaries, [25, 75])
iqr     = q3 - q1
iqr_outliers = [s for s in salaries
                if s < q1 - 1.5*iqr or s > q3 + 1.5*iqr]
print(f"IQR outliers:               {iqr_outliers}")

# ── Z-Score Method ───────────────────────────────────────────
mean = np.mean(salaries)
std  = np.std(salaries, ddof=1)
z_scores = [(s - mean) / std for s in salaries]
z_outliers = [s for s, z in zip(salaries, z_scores) if abs(z) > 2]
print(f"Z-score outliers (|z| > 2): {z_outliers}")
print(f"CTO z-score: {z_scores[-1]:.2f}")
print(f"Z-score outliers (|z| > 3): {[s for s, z in zip(salaries, z_scores) if abs(z) > 3]}")

# With n values, no point can ever have |z| above (n - 1) / sqrt(n)
n = len(salaries)
print(f"Largest possible |z| with n = {n}: {(n - 1) / np.sqrt(n):.2f}")
OUTPUT
IQR outliers: [380000] Z-score outliers (|z| > 2): [380000] CTO z-score: 3.05 Z-score outliers (|z| > 3): [380000] Largest possible |z| with n = 12: 3.18

Here both rules catch the CTO, but only just: the CTO's z-score is 3.05, and with 12 values no point can ever exceed |z| = 3.18. Push the CTO salary in the simulator below and watch the two rules behave differently.

यहाँ दोनों नियम CTO को पकड़ते हैं, पर मुश्किल से: CTO का z-score 3.05 है, और 12 values में कोई point कभी |z| = 3.18 से ऊपर नहीं जा सकता। नीचे के simulator में CTO की salary बदलें और दोनों नियमों का अलग व्यवहार देखें।

这里两条规则都抓到了 CTO,但只是勉强:CTO 的 z 分数是 3.05,而 12 个值里任何点的 |z| 都不可能超过 3.18。在下面的模拟器里调整 CTO 的工资,看两条规则表现有何不同。

LIVELIVE互动Robust vs Non-Robust — Move the CTO SalaryRobust vs Non-Robust — CTO की Salary बदलें稳健 vs 不稳健 — 调整 CTO 工资

Eleven salaries stay fixed. Move the CTO salary: the mean and SD chase it, while the median and IQR (NumPy method) hardly move. The text below compares the two detection rules.

ग्यारह salaries अपनी जगह रहती हैं। CTO की salary बदलें: mean और SD उसके पीछे भागते हैं, जबकि median और IQR (NumPy तरीका) मुश्किल से हिलते हैं। नीचे का text दोनों detection नियमों की तुलना करता है।

其余十一个工资固定不变。调整 CTO 的工资:均值和标准差紧追不放,而中位数和 IQR(NumPy 方法)几乎不动。下方文字比较了两条检测规则。

🎯
Which Should You Use?कौन सा इस्तेमाल करें?该用哪一个?

Default to the IQR when you are unsure — it is robust and makes few assumptions. Use z-scores when the data is roughly normal and the sample is not tiny. For strongly right-skewed data (income, prices), apply the IQR rule to the log of the values, or you will flag many perfectly normal high values — see the next simulator.

पक्का न हो तो default में IQR लें — यह robust है और कम मान्यताएँ रखता है। Z-scores तब इस्तेमाल करें जब data लगभग normal हो और sample बहुत छोटा न हो। बहुत right-skewed data (income, prices) के लिए IQR नियम values के log पर लगाएँ, वरना आप बहुत सी बिल्कुल सामान्य ऊँची values पकड़ लेंगे — अगला simulator देखें।

拿不准时默认用 IQR —— 它稳健,假设也少。数据大致正态且样本不太小时,用 z 分数。对严重右偏的数据(收入、价格),请对数值的对数使用 IQR 规则,否则会把许多完全正常的高值标记出来 —— 见下一个模拟器。


SectionSection第 09 节

When the Fences Fire Too Often — Skewed Dataजब Fences बहुत बार चलें — Skewed Data围栏触发太频繁时 — 偏斜数据

LIVELIVE互动How Many Values Do the 1.5 × IQR Fences Flag?1.5 × IQR Fences कितनी Values पकड़ते हैं?1.5 × IQR 围栏会标记多少个值?

2,000 values. Red bars are outside the fences. Compare normal data with right-skewed, income-like data, then take the log of the skewed data.

2,000 values. लाल bars fences से बाहर हैं। Normal data की तुलना right-skewed, income जैसे data से करें, फिर skewed data का log लें।

2,000 个值。红色柱子在围栏之外。比较正态数据和类似收入的右偏数据,再对偏斜数据取对数。


SectionSection第 10 节

Complete Pipeline — Detect, Investigate, Handleपूरी Pipeline — पकड़ें, जाँचें, संभालें完整流程 — 检测、调查、处理

import numpy as np
import pandas as pd

# Full dataset — house prices in a neighbourhood (£)
prices = [185000, 192000, 178000, 205000, 195000, 210000,
          188000, 201000, 198000, 185000, 2100000, 175000]

df = pd.DataFrame({"price": prices})

# Step 1 — Calculate quartiles and IQR
q1  = df["price"].quantile(0.25)
q2  = df["price"].quantile(0.50)
q3  = df["price"].quantile(0.75)
iqr = q3 - q1

lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr

print("── Summary Statistics ──────────────────")
print(f"Q1 (25th percentile): £{q1:,.0f}")
print(f"Q2 (Median):          £{q2:,.0f}")
print(f"Q3 (75th percentile): £{q3:,.0f}")
print(f"IQR:                  £{iqr:,.0f}")
print(f"Lower fence:          £{lower_fence:,.0f}")
print(f"Upper fence:          £{upper_fence:,.0f}")

# Step 2 — Flag outliers
df["is_outlier"] = (
    (df["price"] < lower_fence) |
    (df["price"] > upper_fence)
)

print("\n── Outliers Detected ───────────────────")
print(df[df["is_outlier"]])

# Step 3 — Compare mean before and after
mean_with    = df["price"].mean()
mean_without = df[~df["is_outlier"]]["price"].mean()
median       = df["price"].median()

print("\n── Impact of Outlier ───────────────────")
print(f"Mean with outlier:    £{mean_with:,.0f}")
print(f"Mean without outlier: £{mean_without:,.0f}")
print(f"Median (robust):      £{median:,.0f}")
OUTPUT
── Summary Statistics ────────────────── Q1 (25th percentile): £185,000 Q2 (Median): £193,500 Q3 (75th percentile): £202,000 IQR: £17,000 Lower fence: £159,500 Upper fence: £227,500 ── Outliers Detected ─────────────────── price is_outlier 10 2100000 True ── Impact of Outlier ─────────────────── Mean with outlier: £351,000 Mean without outlier: £192,000 Median (robust): £193,500

One £2.1 million house lifts the mean from £192,000 to £351,000, while the median stays at £193,500. Before deciding what to do, check the listing: is it a typo (£210,000?) or a real mansion in the same street?

एक £2.1 million का घर mean को £192,000 से £351,000 कर देता है, जबकि median £193,500 पर रहता है। क्या करना है, यह तय करने से पहले listing जाँचें: क्या यह typo है (£210,000?) या उसी गली में सचमुच का बँगला?

一套 £210 万的房子把均值从 £192,000 拉到 £351,000,而中位数仍是 £193,500。决定怎么处理之前,先核对挂牌信息:是笔误(£210,000?),还是同一条街上真有一座豪宅?


SectionSection第 11 节

Golden RulesGolden Rules黄金法则

🎯 Quartiles, IQR and Outliers — Key RulesQuartiles, IQR और Outliers — मुख्य नियम四分位数、IQR 与离群点 — 关键规则
1
Always sort the data before finding quartiles by hand. The method depends on position — unsorted data gives wrong quartiles. (Library functions sort for you.)
हाथ से quartiles निकालने से पहले हमेशा data sort करें। तरीका position पर निर्भर है — बिना sort के quartiles ग़लत आते हैं। (Library functions आपके लिए sort करते हैं।)
手算四分位数之前一定先排序。方法依赖位置 —— 不排序会算错。(库函数会自动排序。)
2
The IQR is robust: the most extreme values sit outside the middle 50%, so making them even more extreme does not move Q1 or Q3. That makes the IQR more reliable than the range or the SD for skewed data.
IQR robust है: सबसे extreme values बीच के 50% से बाहर होती हैं, इसलिए उन्हें और extreme करने से Q1 या Q3 नहीं हिलते। इसीलिए skewed data के लिए IQR, range या SD से ज़्यादा भरोसेमंद है।
IQR 很稳健:最极端的值位于中间 50% 之外,把它们变得更极端也不会改变 Q1 或 Q3。因此对偏斜数据,IQR 比极差或标准差更可靠。
3
Quartile methods differ. NumPy and pandas interpolate by default; the hand method uses halves. Pick one, use it consistently, and state it in reports.
Quartile के तरीके अलग होते हैं। NumPy और pandas default में interpolate करते हैं; हाथ वाला तरीका आधे हिस्से इस्तेमाल करता है। एक चुनें, लगातार इस्तेमाल करें, और reports में बताएँ।
四分位数的算法各不相同。NumPy 和 pandas 默认插值,手算方法用对半分。选一种,始终如一地使用,并在报告中写明。
4
The 1.5 × IQR fence is a guideline, not a law. Use 3 × IQR for "extreme only", and transform long-tailed data (for example with a log) before applying fences.
1.5 × IQR fence एक दिशानिर्देश है, क़ानून नहीं। "सिर्फ़ extreme" के लिए 3 × IQR लें, और fences लगाने से पहले लंबी पूँछ वाले data को transform करें (जैसे log से)।
1.5 × IQR 围栏是指导原则,不是定律。“只看极端值”时用 3 × IQR;对长尾数据,先变换(例如取对数)再用围栏。
5
Investigate before removing. An outlier is a question, not a mistake. Find out why it exists before you fix, remove, cap, transform or keep it.
हटाने से पहले जाँचें। Outlier एक सवाल है, ग़लती नहीं। ठीक करने, हटाने, cap करने, transform करने या रखने से पहले पता करें कि यह क्यों है।
删除之前先调查。离群点是一个问题,而不是一个错误。在更正、删除、截断、变换或保留之前,先弄清它为什么存在。
6
Report the median and IQR together for skewed data — both are robust. Keep the mean and SD for roughly normal data.
Skewed data के लिए median और IQR साथ बताएँ — दोनों robust हैं। Mean और SD लगभग normal data के लिए रखें।
对偏斜数据,中位数和 IQR 一起报告 —— 两者都稳健。均值和标准差留给大致正态的数据。