
SciPy, a Python library for scientific and technical computing, is notoriously handy for performing statistical tests, namely parametric and non-parametric tests. The latter is particularly useful when data does not meet the assumptions of normality. SciPy makes it easier to conduct these tests by providing robust, ready-to-use functions for common non-parametric methods. This article illustrates how to use some of them programmatically.
Step-by-Step Process
The first step is importing the stats module in SciPy, necessary to perform all kinds of statistical tests, and the numpy library which we’ll use for generating some data samples synthetically.
from scipy import stats import numpy as np
Let’s start by applying one of the most popular non-parametric tests: the Mann-Whitney U test, useful to compare the distributions underlying two data samples or groups. Suppose we collect — or synthetically create, as shown below — customer satisfaction ratings for two different airlines on a 1-5 scale.
airline1_ratings = np.random.choice([1, 2, 3, 4, 5], size=50, p=[0.1, 0.2, 0.4, 0.2, 0.1]) airline2_ratings = np.random.choice([1, 2, 3, 4, 5], size=50, p=[0.05, 0.15, 0.3, 0.3, 0.2])
Note that each set of 50 random ratings is drawn with specified probabilities for each integer rating, therefore not following a normal distribution whatsoever.
Performing the Mann Whitney U test with SciPy boils down to using the stats.mannwhitneyu() method, passing the two data groups as arguments, and the alternative hypothesis is set as two-sided, to check for any kind of differences (either being greater or lower) between the first group and the second one.
stat, p_value = stats.mannwhitneyu(airline1_ratings, airline2_ratings,
alternative='two-sided')
We print the two test outputs and interpret the resulting p-value:
print("Mann-Whitney U test results:")
print(f"statistic: {stat:.3f}")
print(f"p-value: {p_value:.3f}")
print(f"Conclusion: {'Reject' if p_value < 0.05 else 'Fail to reject'} null hypothesis")
print("Interpretation: Customer satisfaction" +
" differs significantly between airlines\n" if p_value < 0.05
else " does not differ significantly between airlines\n")
Possible output:
Mann-Whitney U test results: statistic: 860.000 p-value: 0.005 Conclusion: Reject null hypothesis Interpretation: Customer satisfaction differs significantly between airlines
Remember: there is a statistically significant difference when the p-value falls below 0.05 (or any other significance threshold we may have used instead).
Next, we’ll try out another type of non-parametric test, namely the Wilcoxon signed-rank test, which compares the medians of two related samples to evaluate whether their distributions are different. We’ll perform this test to compare booking times (in minutes) before and after the redesign of an airline’s website, as a means to assess impact in customer experience. To randomly generate these data samples, we’ll resort to the exponential distribution, so that data are skewed.
before_redesign = np.random.exponential(10, 30) after_redesign = np.random.exponential(7, 30)
To perform the test, we use the stats.wilcoxon(), passing the “before” and “after” data samples as arguments, after which results are printed similarly as in the previous example.
print("Wilcoxon signed-rank test results:")
print(f"statistic: {stat:.3f}")
print(f"p-value: {p_value:.3f}")
print(f"Conclusion: {'Reject' if p_value < 0.05 else 'Fail to reject'} null hypothesis")
print("Interpretation:" +
" Website redesign had a significant effect on booking times" if p_value < 0.05
else "Website redesign did not significantly affect booking times")
Possible output:
Wilcoxon signed-rank test results: statistic: 201.000 p-value: 0.529 Conclusion: Fail to reject null hypothesis Website redesign did not significantly affect booking times
Wrapping Up
Through two different tests, we exemplified the use of SciPy library for conducting hypothesis non-parametric testing processes. To conclude, it is worth listing another two methods typically used within the stats module of the library to perform non-parametric tests.
- stats.kruskal: for performing Kruskal-Wallis H tests comparing the distributions of two or more independent samples
- stats.spearmanr: for Spearman Rank correlation tests that assess the intensity and direction of associations between two ranked variables.
