Skip to content
intermediate Phase 7 · Descriptive Statistics

Distribution Shape

Read skewness, kurtosis, and histograms to understand how values are spread.

50m
0 problems
Topic Progress 0%

Why Shape Matters

The Mean and Standard Deviation Tell Only Part of the Story

You have analyzed a dataset and reported that the mean customer age is 35 with a standard deviation of 12. These two numbers are correct. They are also dangerously incomplete.

Consider two very different datasets that both have mean=35 and std=12:

Dataset A — ages are symmetrically distributed around 35. Most customers are in their 20s, 30s, and 40s. The distribution looks like a bell curve.

Dataset B — ages are bimodal. One large group of customers is around 22 (college students), another large group is around 48 (parents). Almost no one is 35.

Both datasets have the same mean and standard deviation. But they describe completely different customer bases. Dataset A is a general-audience product. Dataset B is a product with two distinct user segments. The business implications — marketing strategy, product features, pricing — are entirely different.

This is why you must look at the shape of a distribution, not just its center and spread. Shape reveals the underlying structure of the data: whether it is symmetric or skewed, whether it has one peak or multiple peaks, whether the tails are heavy or light.

The Three Aspects of Shape

Skewness — measures asymmetry. A symmetric distribution has skewness of 0. A right-skewed distribution has a long tail to the right (positive skew). A left-skewed distribution has a long tail to the left (negative skew).

Kurtosis — measures tail heaviness. High kurtosis means the distribution has heavy tails and a sharp peak (more extreme values than a normal distribution). Low kurtosis means light tails and a flatter peak.

Modality — the number of peaks (modes) in the distribution. Unimodal has one peak, bimodal has two, multimodal has more than two. Multiple peaks often indicate distinct subgroups within the data.

How Shape Affects Analysis

Distribution shape determines which statistical methods are valid:

  1. Parametric tests (t-tests, ANOVA, linear regression) assume roughly normal distributions. If the data is heavily skewed, these tests can give misleading results.
  2. Mean vs median — in skewed distributions, the mean is pulled toward the tail. The median is more representative.
  3. Outlier detection — in a normal distribution, values beyond 3 standard deviations are rare. In a heavy-tailed distribution, extreme values are common and should not automatically be treated as outliers.
  4. Model selection — many machine learning models assume normally distributed features. Skewed features may need transformation (log, square root) before modeling.

Visualizing Shape

The fastest way to understand distribution shape is to plot it:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Generate skewed data
np.random.seed(42)
right_skewed = np.random.exponential(scale=2, size=1000)

# Histogram
plt.hist(right_skewed, bins=30, edgecolor='black')
plt.title('Right-Skewed Distribution')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

# Summary statistics
series = pd.Series(right_skewed)
print(f"Mean: {series.mean():.2f}")      # 1.96
print(f"Median: {series.median():.2f}")  # 1.39
print(f"Skewness: {series.skew():.2f}")  # positive value

The histogram immediately reveals the shape. The numbers confirm it: mean > median indicates right skew.

Skewness: Measuring Asymmetry

What Skewness Tells You

Skewness quantifies the degree of asymmetry in a distribution. A perfectly symmetric distribution has a skewness of 0. Real-world data is rarely perfectly symmetric, but the further the skewness is from 0, the more asymmetric the distribution.

Right skew (positive skewness) — the tail extends to the right. The mean is greater than the median. Common in: income, housing prices, transaction amounts, response times, hospital stay lengths.

Left skew (negative skewness) — the tail extends to the left. The mean is less than the median. Common in: exam scores (when most students do well), age at retirement, human lifespan.

Approximately symmetric (skewness near 0) — the distribution is roughly balanced. The mean and median are close. Common in: heights, weights, measurement errors, IQ scores.

Calculating Skewness

In pandas, the .skew() method calculates Fisher-Pearson skewness:

import pandas as pd
import numpy as np

# Right-skewed data (exponential distribution)
right_skewed = pd.Series(np.random.exponential(scale=2, size=1000))
print(f"Right-skewed skewness: {right_skewed.skew():.2f}")  # ~2.0

# Left-skewed data (negated exponential)
left_skewed = pd.Series(-np.random.exponential(scale=2, size=1000))
print(f"Left-skewed skewness: {left_skewed.skew():.2f}")  # ~-2.0

# Symmetric data (normal distribution)
symmetric = pd.Series(np.random.normal(loc=0, scale=1, size=1000))
print(f"Symmetric skewness: {symmetric.skew():.2f}")  # ~0.0

Interpreting Skewness Values

As a rule of thumb:

  • −0.5 to 0.5 — approximately symmetric
  • −1 to −0.5 or 0.5 to 1 — moderately skewed
  • < −1 or > 1 — highly skewed

These are guidelines, not hard rules. The context of the data matters. A skewness of 0.8 in a dataset of human heights would be surprising and might indicate a data quality issue. A skewness of 0.8 in a dataset of website session durations is completely normal.

Why Skewness Matters for Analysis

1. The mean is pulled toward the tail.

In a right-skewed distribution, the mean is greater than the median. In a left-skewed distribution, the mean is less than the median. The more skewed the data, the larger the gap between mean and median.

income = pd.Series([30000, 35000, 40000, 45000, 50000, 55000, 60000, 200000])
print(f"Mean: {income.mean():.0f}")    # 69375
print(f"Median: {income.median():.0f}")  # 47500
print(f"Skewness: {income.skew():.2f}")  # 2.15

The mean income ($69,375) is 46% higher than the median ($47,500) because of the single $200,000 outlier. Reporting the mean without acknowledging the skew would mislead any audience.

2. Parametric tests assume symmetry.

The t-test, ANOVA, and linear regression all assume that the residuals are roughly normally distributed. If your data is heavily skewed, these tests can produce incorrect p-values and confidence intervals. In such cases, you should either transform the data (log transform for right-skewed data) or use non-parametric alternatives (Mann-Whitney U test, Kruskal-Wallis test).

3. Skewness reveals data quality issues.

Unexpected skewness can signal problems:

  • A symmetric variable that suddenly becomes skewed might indicate a data collection change.
  • A variable that should be symmetric (like measurement errors) but is skewed might indicate a systematic bias.
  • Extreme skewness might indicate that two different populations have been mixed together.

Transforming Skewed Data

When you need to use parametric methods on skewed data, transformations can help:

import numpy as np
import pandas as pd

# Right-skewed data
data = pd.Series(np.random.exponential(scale=2, size=1000))

# Log transform (add 1 to handle zeros)
log_transformed = np.log1p(data)

print(f"Original skewness: {data.skew():.2f}")        # ~2.0
print(f"Log-transformed skewness: {log_transformed.skew():.2f}")  # ~0.3

The log transform compresses the right tail more than the left tail, reducing right skewness. Other common transforms include square root (for moderate right skew) and Box-Cox (for more control over the transformation).

Kurtosis and Modality

Kurtosis: Measuring Tail Heaviness

Kurtosis describes the shape of the tails and the peak of a distribution relative to a normal distribution. It answers the question: "Are extreme values more or less common than I would expect in a normal distribution?"

Excess kurtosis (what pandas and scipy report by default) subtracts 3 from the raw kurtosis so that a normal distribution has excess kurtosis of 0:

  • Excess kurtosis > 0 (leptokurtic) — heavy tails, sharp peak. More extreme values than a normal distribution. Common in: financial returns, insurance claims, website traffic.
  • Excess kurtosis ≈ 0 (mesokurtic) — normal-like tails and peak.
  • Excess kurtosis < 0 (platykurtic) — light tails, flat peak. Fewer extreme values than a normal distribution. Common in: uniform distributions, some test scores.
import pandas as pd
import numpy as np
from scipy import stats

# Leptokurtic (heavy tails)
heavy_tails = pd.Series(np.random.standard_t(df=3, size=1000))
print(f"Heavy tails kurtosis: {heavy_tails.kurtosis():.2f}")  # positive

# Mesokurtic (normal-like)
normal = pd.Series(np.random.normal(loc=0, scale=1, size=1000))
print(f"Normal kurtosis: {normal.kurtosis():.2f}")  # ~0

# Platykurtic (light tails)
uniform = pd.Series(np.random.uniform(low=-1, high=1, size=1000))
print(f"Uniform kurtosis: {uniform.kurtosis():.2f}")  # negative

Why Kurtosis Matters

Kurtosis is often overlooked, but it has practical implications:

1. Risk assessment. In finance, high kurtosis means extreme events (market crashes, huge gains) are more likely than a normal distribution would predict. Models that assume normality will underestimate risk.

2. Outlier detection. In a high-kurtosis distribution, extreme values are a natural feature of the data, not anomalies. Automatically removing them as outliers would discard meaningful information.

3. Model assumptions. Many statistical models assume normality. High kurtosis violates this assumption and can lead to incorrect confidence intervals and hypothesis tests.

Modality: Counting the Peaks

Modality refers to the number of peaks (local maxima) in a distribution:

  • Unimodal — one peak. The most common shape. Examples: heights, weights, IQ scores.
  • Bimodal — two peaks. Often indicates two distinct subgroups. Examples: heights of a mixed-gender population, exam scores from two different classes.
  • Multimodal — more than two peaks. Indicates multiple subgroups or complex underlying structure.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Bimodal distribution: two groups
np.random.seed(42)
group1 = np.random.normal(loc=20, scale=2, size=500)
group2 = np.random.normal(loc=35, scale=3, size=500)
bimodal = pd.Series(np.concatenate([group1, group2]))

plt.hist(bimodal, bins=30, edgecolor='black')
plt.title('Bimodal Distribution')
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.show()

print(f"Mean: {bimodal.mean():.2f}")    # 27.5 (between the two peaks)
print(f"Median: {bimodal.median():.2f}")  # 27.5 (between the two peaks)

The mean and median both fall between the two peaks — in a region where almost no data exists. This is a case where neither measure of central tendency is useful. The bimodal structure is the real story, and it demands segmentation: analyze each group separately.

Detecting Modality

Modality is best detected visually with a histogram or kernel density estimate (KDE):

import seaborn as sns
import matplotlib.pyplot as plt

sns.kdeplot(bimodal, fill=True)
plt.title('KDE of Bimodal Distribution')
plt.show()

The KDE plot clearly shows two peaks. If you see multiple peaks, investigate whether the data contains distinct subgroups that should be analyzed separately. Common causes of multimodal data:

  • Mixing data from different populations (e.g., men and women, different regions, different time periods)
  • Mixing data from different processes (e.g., weekday vs weekend behavior)
  • A categorical variable that was not properly segmented

Shape and Model Choice

How Distribution Shape Determines Your Analytical Toolkit

The shape of your data is not just a descriptive detail — it determines which statistical methods and models are valid. Using a method that assumes normality on heavily skewed data is like using a screwdriver to hammer a nail: you might get a result, but it will not be the right one.

Decision Framework: Shape → Method

Approximately symmetric, no outliers:

  • Use mean and standard deviation
  • Parametric tests (t-test, ANOVA, Pearson correlation) are valid
  • Linear regression assumptions are satisfied

Moderately skewed:

  • Report median and IQR alongside mean and std
  • Consider data transformation (log, square root)
  • Parametric tests may still be valid with large samples (Central Limit Theorem)

Heavily skewed:

  • Use median and IQR as primary measures
  • Transform data before parametric analysis, or use non-parametric tests
  • Consider robust regression methods

Bimodal or multimodal:

  • Do not summarize with a single mean or median
  • Segment the data and analyze each mode separately
  • Investigate what distinguishes the subgroups

Heavy tails (high kurtosis):

  • Do not automatically remove extreme values
  • Use robust statistical methods
  • In financial contexts, use models that account for fat tails

Practical Example: Choosing Methods Based on Shape

You are analyzing the relationship between advertising spend and sales. The sales data is right-skewed (most days have moderate sales, a few days have very high sales).

import pandas as pd
import numpy as np
from scipy import stats

np.random.seed(42)
ad_spend = np.random.uniform(100, 1000, size=200)
sales = 2 * ad_spend + np.random.exponential(scale=50, size=200)

df = pd.DataFrame({'ad_spend': ad_spend, 'sales': sales})

print(f"Sales skewness: {df['sales'].skew():.2f}")  # positive
print(f"Sales kurtosis: {df['sales'].kurtosis():.2f}")  # positive

The sales data is right-skewed with heavy tails. Your options:

Option 1: Transform the data

df['log_sales'] = np.log1p(df['sales'])
print(f"Log-sales skewness: {df['log_sales'].skew():.2f}")  # closer to 0

# Now Pearson correlation is more valid
r, p = stats.pearsonr(df['ad_spend'], df['log_sales'])
print(f"Pearson r: {r:.3f}, p: {p:.4f}")

Option 2: Use non-parametric methods

# Spearman correlation does not assume normality
rho, p = stats.spearmanr(df['ad_spend'], df['sales'])
print(f"Spearman rho: {rho:.3f}, p: {p:.4f}")

Option 3: Use robust regression

from sklearn.linear_model import HuberRegressor

model = HuberRegressor()
model.fit(df[['ad_spend']], df['sales'])
print(f"Robust slope: {model.coef_[0]:.3f}")

Each approach is valid. The choice depends on your audience, your data, and the questions you are answering. The key is to recognize the shape and choose deliberately, not by default.

Shape as a Diagnostic Tool

Distribution shape is not just about choosing methods — it is a diagnostic tool that reveals what is happening in your data:

  • Unexpected skew might indicate a data collection change or a genuine shift in behavior.
  • Unexpected modality might indicate mixed populations or a process change.
  • Heavy tails might indicate rare but important events that deserve special attention.
  • Light tails might indicate that the data has been truncated or filtered.

Always plot your data before analyzing it. The shape you see will guide every subsequent decision.

Practice Problems

0 / 2 solved
Identify Skewness Direction

For each dataset, determine whether it is right-skewed, left-skewed, or approximately symmetric. Explain your reasoning. (a) [1, 2, 3, 4, 5, 6, 7, 8, 9, 100], (b) [1, 90, 91, 92, 93, 94, 95, 96, 97, 98], (c) [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

Solution
import pandas as pd

data_a = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 100])
data_b = pd.Series([1, 90, 91, 92, 93, 94, 95, 96, 97, 98])
data_c = pd.Series([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])

print(f"A skewness: {data_a.skew():.2f}")  # ~3.0 (right-skewed)
print(f"B skewness: {data_b.skew():.2f}")  # ~-3.0 (left-skewed)
print(f"C skewness: {data_c.skew():.2f}")  # ~0.0 (symmetric)

# (a) Right-skewed: the value 100 creates a long right tail
# (b) Left-skewed: the value 1 creates a long left tail
# (c) Symmetric: values are evenly spaced around the center
Bimodal Data Segmentation

A dataset of customer ages has two peaks: one at age 25 and one at age 55. The mean age is 40. Explain why the mean is not a useful summary and what you should do instead.

Solution
The mean age of 40 falls between the two peaks — in a region where almost no customers exist. Neither the mean nor the median is useful because the data is bimodal.

The correct approach is to segment the data into two groups (e.g., using clustering or a threshold) and analyze each group separately:

```python
young = ages[ages < 40]
old = ages[ages >= 40]

print(f"Young group - Mean: {young.mean():.1f}, Std: {young.std():.1f}")
print(f"Old group - Mean: {old.mean():.1f}, Std: {old.std():.1f}")
```

The bimodal structure likely indicates two distinct customer segments (e.g., students and professionals). Each segment should be analyzed and reported separately.

Quiz

1. A distribution has a long tail extending to the right. What is the relationship between the mean and median?

Question 1 options

2. What does a high excess kurtosis value indicate about a distribution?

Question 2 options

3. A histogram of customer ages shows two distinct peaks at ages 22 and 48. What is the most appropriate analytical approach?

Question 3 options

Flashcards

Question

What does positive skewness indicate?

Answer

Positive skewness indicates a right-skewed distribution: the tail extends to the right, and the mean is greater than the median. Common in income, prices, and response times.

Question

What is excess kurtosis and what does a positive value mean?

Answer

Excess kurtosis measures tail heaviness relative to a normal distribution (which has excess kurtosis = 0). Positive excess kurtosis means heavy tails and a sharp peak — extreme values are more common than in a normal distribution.

Question

What does a bimodal distribution suggest about the data?

Answer

A bimodal distribution suggests the data contains two distinct subgroups. The mean and median fall between the peaks and are not useful summaries. Segment the data and analyze each group separately.

Question

How does skewness affect the choice between parametric and non-parametric tests?

Answer

Parametric tests (t-test, ANOVA) assume roughly normal distributions. Heavily skewed data violates this assumption, potentially producing incorrect results. Use data transformation or non-parametric alternatives (Mann-Whitney U, Kruskal-Wallis) for skewed data.

Revision Notes

Key Takeaways

  • 1. Skewness measures asymmetry: positive = right tail, negative = left tail, zero = symmetric
  • 2. Kurtosis measures tail heaviness: positive = heavy tails, negative = light tails
  • 3. Modality reveals subgroup structure: multiple peaks mean multiple populations
  • 4. Distribution shape determines which statistical methods are valid — always check shape before choosing a method
  • 5. Bimodal data should be segmented and analyzed separately, not summarized with a single mean or median

Interview Tips

  • • When given a dataset, always mention skewness and modality before discussing central tendency
  • • Be ready to explain why parametric tests assume normality and what to do when data is skewed
  • • If you see a bimodal distribution in an interview, proactively suggest segmentation rather than reporting a single summary statistic

Cheat Sheet

Cheat Sheet: Distribution Shape

Skewness

  • Positive (> 0) — right-skewed, tail to the right, mean > median
  • Negative (< 0) — left-skewed, tail to the left, mean < median
  • ≈ 0 — approximately symmetric, mean ≈ median
  • Guidelines: ±0.5 symmetric, ±1 moderate, >1 high

Kurtosis (Excess)

  • > 0 (leptokurtic) — heavy tails, sharp peak
  • ≈ 0 (mesokurtic) — normal-like
  • < 0 (platykurtic) — light tails, flat peak

Modality

  • Unimodal — one peak, single population
  • Bimodal — two peaks, two subgroups
  • Multimodal — multiple peaks, multiple subgroups

Shape → Method

  • Symmetric → mean, std, parametric tests
  • Skewed → median, IQR, transform or non-parametric
  • Bimodal → segment, analyze separately

Code

series.skew()       # skewness
series.kurtosis()   # excess kurtosis
np.log1p(series)    # log transform for right skew

Continue Learning

Before You Start

Related Reading