How to Perform Welch's t-Test in Python

Calculate the Welch t-statistic and degrees of freedom for two samples with unequal variances using Python's statistics module.

Medium Python 3.8+ Aug 9, 2026 A/B testing & experimentation 13 views 0 copies

Python code

28 lines
Python 3.8+
import math
from statistics import mean, variance


def welch_t_test(sample1, sample2):
    n1, n2 = len(sample1), len(sample2)
    mean1, mean2 = mean(sample1), mean(sample2)
    var1, var2 = variance(sample1), variance(sample2)

    # Welch's t statistic
    t_stat = (mean1 - mean2) / math.sqrt(var1 / n1 + var2 / n2)

    # Welch–Satterthwaite degrees of freedom
    df_num = (var1 / n1 + var2 / n2) ** 2
    df_den = ((var1 / n1) ** 2) / (n1 - 1) + ((var2 / n2) ** 2) / (n2 - 1)
    df = df_num / df_den

    return t_stat, df


if __name__ == "__main__":
    # Mock data: two groups with unequal variances
    group_a = [5.1, 6.2, 5.4, 6.8, 5.9, 6.1]
    group_b = [8.5, 7.9, 8.2, 7.5, 8.0, 7.8, 8.4]

    t_statistic, degrees_freedom = welch_t_test(group_a, group_b)
    print(f"t-statistic: {t_statistic:.4f}")
    print(f"degrees of freedom: {degrees_freedom:.4f}")

Output

stdout
t-statistic: -6.0439
degrees of freedom: 10.3700

How it works

Welch's t-test adapts Student's t-test for samples with unequal variances and unequal sizes. The t-statistic uses each sample's variance divided by its own size, avoiding the pooled variance assumption. The degrees of freedom are computed with the Welch–Satterthwaite equation, which can be fractional. This function returns only the statistic and degrees of freedom; to get a p-value you must use the cumulative distribution function from scipy.stats.t or the scipy.stats.ttest_ind function with equal_var=False.

Common mistakes

  • Using the pooled variance formula instead of Welch's when variances differ.
  • Forgetting that `statistics.variance` uses Bessel's correction (sample variance, not population).
  • Assuming degrees of freedom will be an integer; it can be fractional.
  • Not accounting for unequal sample sizes when computing degrees of freedom.

Variations

  1. Use `scipy.stats.ttest_ind(sample1, sample2, equal_var=False)` to get the p-value directly.
  2. Compute the p-value with `scipy.stats.t.sf(abs(t_stat), df) * 2` for a two-tailed test.

Real-world use cases

  • Comparing conversion rates between a control and a new feature when sample sizes and variances differ.
  • A/B testing two pricing models where user traffic and response variability are not equal.
  • Evaluating model performance metrics (e.g., latency) across two server clusters with different loads.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from A/B testing & experimentation

Related tutorials and quizzes for this topic.