Outlier detection with IQR in Pandas - Time & Space Complexity
We want to understand how the time needed to find outliers using IQR changes as the data grows.
How does the work increase when we have more data points?
Analyze the time complexity of the following code snippet.
import pandas as pd
# Assume df is a DataFrame with a numeric column 'values'
Q1 = df['values'].quantile(0.25)
Q3 = df['values'].quantile(0.75)
IQR = Q3 - Q1
outliers = df[(df['values'] < (Q1 - 1.5 * IQR)) | (df['values'] > (Q3 + 1.5 * IQR))]
This code calculates the IQR and finds rows where values are outliers based on that range.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Pandas
quantileinternally sorts the 'values' column (O(n log n)) to compute order statistics, plus O(n) filtering. - How many times: Two quantile calls (each O(n log n)) and one filtering pass (O(n)); dominated by sorting.
As the number of data points grows, the time grows as O(n log n) due to sorting in quantiles.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 70 (2 sorts ~60 + 10 filter) |
| 100 | About 1,400 |
| 1000 | About 21,000 |
Pattern observation: Doubling n more than doubles the work due to the log n factor.
Time Complexity: O(n log n)
Dominated by sorting within pandas quantile calls.
[X] Wrong: "It's O(n) because we just scan the data a few times."
[OK] Correct: quantile requires sorting to find precise percentiles, costing O(n log n).
Understanding how data size affects outlier detection helps you explain your approach clearly and shows you think about efficiency in real data tasks.
"Pandas quantile uses sorting (O(n log n)). What if we used a linear-time selection algorithm (like quickselect) for exact quantiles? How would complexity change?"
Practice
Solution
Step 1: Understand quartiles
Quartiles divide data into four equal parts. Q1 is the 25th percentile, Q3 is the 75th percentile.Step 2: Define IQR
IQR is the difference between Q3 and Q1, showing the middle 50% spread of data.Final Answer:
The range between the 25th percentile (Q1) and the 75th percentile (Q3) -> Option AQuick Check:
IQR = Q3 - Q1 [OK]
- Confusing IQR with total range
- Thinking IQR is the average
- Mixing up quartiles with percentiles
df['score']?Solution
Step 1: Recall IQR formula
IQR is Q3 minus Q1, where Q3 is 75th percentile and Q1 is 25th percentile.Step 2: Check pandas quantile usage
Usingquantile(0.75)andquantile(0.25)correctly gets Q3 and Q1.Final Answer:
iqr = df['score'].quantile(0.75) - df['score'].quantile(0.25) -> Option CQuick Check:
Use quantile(0.75) - quantile(0.25) for IQR [OK]
- Using mean or median instead of quantiles
- Using max-min instead of IQR
- Using standard deviation instead of IQR
outliers?
import pandas as pd
data = {'values': [10, 12, 14, 15, 18, 100, 105]}
df = pd.DataFrame(data)
Q1 = df['values'].quantile(0.25)
Q3 = df['values'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df[(df['values'] < lower_bound) | (df['values'] > upper_bound)]
print(outliers)Solution
Step 1: Calculate Q1, Q3, and IQR
Q1 = 12.0 (between 12 and 14), Q3 = 18.0 (between 18 and 100), IQR = 6.0.Step 2: Calculate bounds and find outliers
Lower bound = 12 - 1.5*6 = 3; Upper bound = 18 + 1.5*6 = 27. Values 100 and 105 are above upper bound, so they are outliers.Final Answer:
Rows with values 100 and 105 -> Option BQuick Check:
Outliers > Q3 + 1.5*IQR or < Q1 - 1.5*IQR: 100, 105 [OK]
- Miscomputing Q1 or Q3
- Using wrong inequality signs
- Ignoring both lower and upper bounds
Q1 = df['data'].quantile(0.25) Q3 = df['data'].quantile(0.75) IQR = Q3 - Q1 outliers = df[(df['data'] > Q3 + 1.5 * IQR) & (df['data'] < Q1 - 1.5 * IQR)]
Solution
Step 1: Understand outlier condition
Outliers are values less than lower bound OR greater than upper bound, so conditions should be combined with OR (|).Step 2: Check code condition
The code uses AND (&), which means no value can be both greater than upper bound and less than lower bound simultaneously.Final Answer:
The condition uses '&' instead of '|' to combine bounds -> Option DQuick Check:
Use '|' for outlier condition, not '&' [OK]
- Using AND instead of OR for outlier filtering
- Swapping Q1 and Q3 values
- Calculating IQR incorrectly
df with a column 'height'. You want to remove outliers using IQR but keep the original index. Which code correctly filters out outliers and keeps the index intact?Solution
Step 1: Calculate IQR and bounds correctly
Calculate Q1, Q3, and IQR. Define lower bound as Q1 - 1.5*IQR and upper bound as Q3 + 1.5*IQR.Step 2: Filter rows within bounds and keep index
Use boolean indexing with AND (&) to keep rows inside bounds. Do not reset index to keep original indices.Final Answer:
Code in option A correctly filters and keeps index -> Option AQuick Check:
Filter with AND inside bounds, no reset_index [OK]
- Using OR instead of AND to filter
- Resetting index and losing original row labels
- Swapping bounds or using wrong inequalities
Ready to prove it?
Pass the test and this pattern moves unknown
