5 Descriptive Statistics You Should Always Check First

โฑ๏ธ 4 min read ๐Ÿ“Š Data Analysis

The five descriptive statistics to check first are the mean versus the median, the standard deviation, the minimum and maximum, the quartiles (25th, 50th and 75th percentiles), and the count of non-missing values. Together they reveal skew, spread, impossible values and missing data before you start any deeper analysis.

Quick answer: Before any analysis, check (1) mean vs median for skew, (2) standard deviation for spread, (3) min and max for impossible values, (4) the 25th, 50th and 75th percentiles and the IQR (Q3 โˆ’ Q1), and (5) the non-missing count against the row count. In pandas, df.describe() returns all of these except the missing count, which df.isna().sum() gives you.

How do the mean and median show skewness?

Compare them: a mean well above the median signals right skew (a few high values pull the mean up), a mean below the median signals left skew, and a mean close to the median suggests a roughly symmetric distribution. For example, a $75,000 mean salary against a $58,000 median means a minority of high earners is lifting the average.

Mean: Average of all values (sensitive to outliers)

Median: Middle value (robust to outliers)

# Python
df['salary'].mean()   # 75,000
df['salary'].median() # 58,000

What this tells you:

What does the standard deviation tell you?

The standard deviation measures how far values typically sit from the mean, in the same units as the data. A low standard deviation means values cluster near the mean; a high one means they are spread out.

# Python (pandas returns the sample standard deviation)
df['age'].std()  # 12.5

# SQL: sample standard deviation, same as pandas
SELECT STDDEV_SAMP(age) FROM users;

Rules of thumb (for roughly normal data):

These percentages come from the normal distribution. For skewed data they do not hold, so describe the spread with percentiles instead. See standard deviation explained for how it is calculated.

Why should you check the min and max?

The minimum and maximum are the quickest way to catch impossible values, placeholder codes and data entry errors, such as a customer age of 0 or 150.

df['age'].min()  # 0  โ† Suspicious! Baby customers?
df['age'].max()  # 150 โ† Data entry error!

Check for:

What do the 25th and 75th percentiles tell you?

Quartiles split the sorted data into four equal-sized groups: roughly a quarter of values fall below Q1 (the 25th percentile), half below the median, and three quarters below Q3 (the 75th percentile). More on the calculation in percentiles and quartiles explained.

# Python
df['price'].quantile([0.25, 0.5, 0.75])

# Result:
0.25    19.99  โ† 25th percentile (Q1)
0.50    39.99  โ† 50th percentile (median)
0.75    79.99  โ† 75th percentile (Q3)

Interquartile Range (IQR) = Q3 - Q1

IQR tells you the range of the middle 50% of data (less affected by outliers than range). The common outlier rule flags values below Q1 โˆ’ 1.5 ร— IQR or above Q3 + 1.5 ร— IQR (see outlier detection).

How do you check the count and missing values?

Compare each column's non-missing count with the total number of rows: pandas' count() skips missing values, so any gap between the two is missing data.

# Python
df['email'].count()        # 8,500
df['email'].isna().sum()   # 1,500 missing

# Percentage missing
df['email'].isna().mean() * 100  # 15% missing

Questions to ask:

For what to do next, see handling missing data.

How do I get these statistics at once in pandas?

Run df.describe(): it returns the count, mean, standard deviation, min, quartiles and max for every numeric column in one table.

# Python: Get all at once
df.describe()

# Output:
       age         salary       experience
count  10000.0    10000.0    10000.0
mean   35.5       75000.0    8.2
std    12.3       45000.0    5.1
min    18.0       25000.0    0.0
25%    27.0       45000.0    4.0
50%    34.0       58000.0    7.0
75%    43.0       95000.0    12.0
max    65.0       250000.0   30.0

How do you interpret describe() output?

Read it in the same order as the five checks. For these ten order values, the mean (61.70) is more than double the median (23.50), the standard deviation (119.19) is larger than the mean, and the max (400) is far above Q3 (33.75), which all point to at least one extreme value on the high end.

import pandas as pd

orders = pd.Series([12, 15, 18, 20, 22, 25, 30, 35, 40, 400])
print(orders.describe().round(2))

# count     10.00
# mean      61.70
# std      119.19
# min       12.00
# 25%       18.50
# 50%       23.50
# 75%       33.75
# max      400.00
# dtype: float64

The IQR is 33.75 โˆ’ 18.50 = 15.25, so the upper outlier fence is 33.75 + 1.5 ร— 15.25 = 56.625, and 400 is the only value above it. Remove it and the mean falls from 61.7 to 24.1, while the median only moves from 23.5 to 22.

Red Flags to Look For

These patterns usually point to outliers, data quality problems or uneven missing data, and each one is worth investigating before you report a number.

What are common mistakes with descriptive statistics?

The most common mistake is mixing up the sample and population standard deviation: pandas' .std() divides by n โˆ’ 1 (sample), while NumPy's np.std() divides by n (population), so the same column gives two different answers.

import numpy as np
import pandas as pd

values = [2, 4, 4, 4, 5, 5, 7, 9]
print(round(pd.Series(values).std(), 2))  # 2.14  sample (ddof=1)
print(np.std(values))                     # 2.0   population (ddof=0)
print(round(np.std(values, ddof=1), 2))   # 2.14  matches pandas

Golden Rule: Never skip descriptive statistics. Five minutes of checking these stats can save hours of debugging bad analysis later.

โ† Back to Data Analysis Tips