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 (£)工资(£) |
|---|---|---|
| 1 | Junior DeveloperJunior Developer初级开发 | 32,000 |
| 2 | Junior DeveloperJunior Developer初级开发 | 34,000 |
| 3 | Junior DeveloperJunior Developer初级开发 | 33,000 |
| 4 | Mid DeveloperMid Developer中级开发 | 48,000 |
| 5 | Mid DeveloperMid Developer中级开发 | 51,000 |
| 6 | Mid DeveloperMid Developer中级开发 | 49,000 |
| 7 | Senior DeveloperSenior Developer高级开发 | 72,000 |
| 8 | Senior DeveloperSenior Developer高级开发 | 75,000 |
| 9 | Senior DeveloperSenior Developer高级开发 | 78,000 |
| 10 | Lead DeveloperLead Developer开发组长 | 95,000 |
| 11 | Engineering ManagerEngineering Manager工程经理 | 120,000 |
| 12 | CTOCTO首席技术官(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 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 能更诚实地告诉你数据的中间在哪里 —— 还提供了一条标记异常值的简单规则。
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% 的数值。共有三个四分位数:
- Lower quartileLower quartile下四分位数
- About 25% of data belowलगभग 25% data नीचे约 25% 的数据在它下面
- About 75% of data aboveलगभग 75% data ऊपर约 75% 的数据在它上面
- The medianMedian就是中位数
- 50% of data below50% data नीचे50% 的数据在它下面
- 50% of data above50% data ऊपर50% 的数据在它上面
- Upper quartileUpper quartile上四分位数
- About 75% of data belowलगभग 75% data नीचे约 75% 的数据在它下面
- About 25% of data aboveलगभग 25% data ऊपर约 25% 的数据在它上面
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 的冲刺者,都可能是离群点。
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 默认方法之间切换 —— 它们给出的四分位数可能略有不同。
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% —— 典型范围 —— 并忽略极低和极高的值。
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)。超出围栏的值单独画成一个点。
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。
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]
[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 values[4, 7, 9, 12, 15, 18, 21, 24, 28, 35, 38, 45] —— n = 12[4, 7, 9, 12, 15, 18]: (9 + 12) / 2 = 10.5[4, 7, 9, 12, 15, 18] का median: (9 + 12) / 2 = 10.5[4, 7, 9, 12, 15, 18] 的中位数:(9 + 12) / 2 = 10.5[21, 24, 28, 35, 38, 45]: (28 + 35) / 2 = 31.5[21, 24, 28, 35, 38, 45] का median: (28 + 35) / 2 = 31.5[21, 24, 28, 35, 38, 45] 的中位数:(28 + 35) / 2 = 31.5With 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 个)。也有教材会把它放进去 —— 这也是不同工具给出的四分位数略有差异的原因之一。
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) —— 超出这些边界的值被标记为离群点。箱线图用的正是这条规则。
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 लगाना把围栏用到工资数据上
[32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380][32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380][32, 33, 34, 48, 49, 51, 72, 75, 78, 95, 120, 380][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[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.5Upper fence = 86.5 + 1.5 × 45.5 = 154.75
Upper fence = 86.5 + 1.5 × 45.5 = 154.75
上围栏 = 86.5 + 1.5 × 45.5 = 154.75
£380,000 (CTO) > £154,750 → OUTLIER
£120,000 (Engineering Manager) < £154,750 → normal
£380,000 (CTO) > £154,750 → OUTLIER
£120,000 (Engineering Manager) < £154,750 → normal
£380,000(CTO)> £154,750 → 离群点
£120,000(工程经理)< £154,750 → 正常
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。
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。
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}")
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}")
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"]])
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),超出的点以圆圈显示。
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 cm | Fix or removeठीक करें या हटाएँ更正或删除 |
| Measurement errorMeasurement की ग़लती测量错误 | A faulty sensor reports 0 °C on a summer dayख़राब sensor गर्मी के दिन 0 °C बताता है故障传感器在夏天报告 0 °C | Remove (or replace)हटाएँ (या बदलें)删除(或替换) |
| Legitimate extreme valueअसली extreme value真实的极端值 | The CTO really earns £380,000CTO सच में £380,000 कमाता हैCTO 确实挣 £380,000 | Keep — report separately or use robust statisticsरखें — अलग बताएँ या robust statistics इस्तेमाल करें保留 —— 单独报告或使用稳健统计量 |
| Interesting anomalyदिलचस्प anomaly有价值的异常 | A fraudulent transactionएक fraudulent transaction一笔欺诈交易 | Keep — it is the signalरखें — यही असली संकेत है保留 —— 它就是信号 |
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}")
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),这一行留在数据里,却再也无法主导均值。
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×IQR | z = (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}")
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 的工资,看两条规则表现有何不同。
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 方法)几乎不动。下方文字比较了两条检测规则。
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 规则,否则会把许多完全正常的高值标记出来 —— 见下一个模拟器。
When the Fences Fire Too Often — Skewed Dataजब Fences बहुत बार चलें — Skewed Data围栏触发太频繁时 — 偏斜数据
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 个值。红色柱子在围栏之外。比较正态数据和类似收入的右偏数据,再对偏斜数据取对数。
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}")
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?),还是同一条街上真有一座豪宅?