EDA and Feature Engineeringpandas 3.0 · scikit-learn 1.9 · seaborn 0.13 · Python 3.12+
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
72 small wins to finish your pathNext lesson →

What an outlier is

An outlier is a value in a column that sits far away from the rest of that column, far enough that the summaries you compute and the model you fit come out different because of it.

Last updated: 12 Oct, 2026 · pandas 3.0 · scikit-learn 1.9

The missing-value part filled the holes in a column. A column can also carry the opposite problem: a value that is present, is a number, and is either wrong by a mile or true and rare. SimpleImputer in scikit-learn left every row in place, which is where this part starts.

Measuring what one far value costs

A column of 34 sensor readings

These are 34 readings of the same thing. Most of them sit between 10 and 19. Three of them do not.

python
readings = [11, 10, 12, 14, 12, 15, 14, 13, 15, 102, 12, 14, 17, 19, 107,
            10, 13, 12, 14, 12, 108, 12, 11, 14, 13, 15, 10, 15, 12, 10, 14, 13, 15, 10]

The same column with the three far values removed

A boolean mask keeps the rows whose value is under 50. That cut-off was chosen by eye, which is the reason the next two lessons exist: the z score and the IQR fence replace the eye with a rule.

python
clean = s[s < 50]     # the same column, three values short

Reading the column twice

The mean, the median and the standard deviation of the full column, then of the 31 values that are left.

Example34 readings, with and without the three far values
import pandas as pd

readings = [11, 10, 12, 14, 12, 15, 14, 13, 15, 102, 12, 14, 17, 19, 107,
            10, 13, 12, 14, 12, 108, 12, 11, 14, 13, 15, 10, 15, 12, 10, 14, 13, 15, 10]
s = pd.Series(readings)
clean = s[s < 50]     # the same column, three values short

print("all 34  :  mean", round(s.mean(), 2), " median", s.median(),
      " std", round(s.std(), 2))
print("other 31:  mean", round(clean.mean(), 2), " median", clean.median(),
      " std", round(clean.std(), 2))
print("largest of the other 31:", clean.max())

What the two rows show

  • The mean moved from 21.18 to 13.0. Three values out of 34 dragged the average of the column 63% above where the other 31 readings sit.
  • The median did not move. It was 13.0 both times. The median is a position in the sorted column, so how far away a value sits changes nothing as long as it stays on the same side.
  • The standard deviation went from 26.77 to 2.14. The spread of the column, as the number most models use, was more than twelve times too large.
  • The largest of the other 31 is 19. So 102, 107 and 108 are not slightly high. They are five times the typical reading.

No error was raised. Both columns are valid numbers and pandas computed both answers correctly. That is what makes an outlier a reading problem rather than a crash.

Plotting the 34 readings on one line

One dot per reading on a single axis. The shape of the problem is easier to see than to describe.

ExampleEvery reading as one dot, with the three far values in red
import matplotlib
matplotlib.use("svg")
import matplotlib.pyplot as plt
import numpy as np

readings = [11, 10, 12, 14, 12, 15, 14, 13, 15, 102, 12, 14, 17, 19, 107,
            10, 13, 12, 14, 12, 108, 12, 11, 14, 13, 15, 10, 15, 12, 10, 14, 13, 15, 10]
values = np.array(readings)
position = np.arange(1, len(values) + 1)   # where each reading sits in the list
far = values >= 50

fig, ax = plt.subplots(figsize=(7, 2.8))
ax.scatter(values[~far], position[~far], s=45, color="#3a6fd8", label="the other 31")
ax.scatter(values[far], position[far], s=45, color="#d64541", label="far from the rest")
ax.set_xlabel("reading")
ax.set_ylabel("position in the column")
ax.legend(loc="center")
fig.savefig("chart.svg")

print("near:", int((~far).sum()), " far:", int(far.sum()))
A scatter of the 34 readings, each one plotted at its value along the horizontal axis and its position in the column up the vertical axis. Thirty-one blue points form a narrow band between 10 and 19, and three red points sit far to the right near 102, 107 and 108, with a wide empty gap between the two groups.

The gap between 19 and 102 is the thing every detection rule in this part is trying to put a number on.

Which models a far value moves

A far value is a problem for the model you chose, not for the dataset in general. Anything that adds every row into one total feels it. Anything that reads order or counts does not.

Two panels list which models a single far value moves. The left panel, pulled by a far value, holds linear regression, logistic regression, K-Means, PCA, neural networks and standardisation, because each one adds every row into a single sum or distance. The right panel, barely moved, holds decision trees, random forest, gradient boosting, naive Bayes, K nearest neighbours and the median with the IQR, because each one reads order or counts rather than sizes.

An outlier, an error and a rare truth

What it isExampleWhat to do with it
Data errora value that was never truean age of 300, a price of -1fix it, or treat it as missing
Rare trutha real value from the tail of the columna fare of 512 on the Titanickeep it, and pick a model that tolerates it
Another populationa row that belongs to a different groupa wholesale order in a retail tablemodel it separately, or add a flag column
Noiseordinary scatter, not far from the resta reading of 19 among readings of 10 to 15leave it alone

The first three look identical in a box plot. A chart finds the candidates; what a candidate is comes from knowing where the data came from.

Where a far value changes the answer

  • Before computing a mean to fill holes. Mean imputation on the 34 readings would write 21.18 into every gap, a value larger than 31 of the 34 readings that exist.
  • Before scaling. Standardisation divides by the standard deviation, so the 26.77 above would squash the real variation of the column into almost nothing.
  • Before fitting a linear or logistic model. Both add a loss over every row, so a row far from the rest contributes most of the total and most of the gradient.
Watch out. A value is an outlier only with respect to a column and a question. A fare of 512 is far from the other fares and is still a true fare paid by a real passenger. Deleting rows because a rule flagged them, without looking at what the rows are, throws away the part of the data a model most needs to learn from.
Try it yourself
  • Change the cut-off in s[s < 50] to 20 and read the three numbers again. Nothing moves, because no reading sits between 19 and 102.
  • Add one more reading of 500 to the list and print the mean and the median again. One of the two moves a long way and the other does not.
  • Replace the three far values with 16, 17 and 18 and print the standard deviation. Compare it with the 2.14 of the other 31.

You understood something today that you didn't yesterday.