10 Python One-Liners to Run Common Statistical Tests

10 Python One-Liners to Run Common Statistical Tests
Image by Author | ChatGPT

Statistical tests form the backbone of data analysis, helping us validate assumptions, compare groups, and detect patterns in our data. While Python offers several libraries for statistical analysis, each has its own strengths and use cases. In this article, we’ll explore 10 Python one-liners that showcase the progression from basic statistical tests to sophisticated analyses.

We’ll start with SciPy’s straightforward approach, move to Statsmodels’ comprehensive output, and finish with Pingouin’s modern, user-friendly interface. Each example demonstrates how different libraries handle the same statistical concepts, giving you the flexibility to choose the right tool for your analysis.

Getting Started with SciPy

SciPy’s stats module provides the foundation for statistical testing in Python. Its functions return essential test statistics and p-values without unnecessary complexity. We’ll demonstrate these tests using the classic Iris dataset, which contains measurements of sepal length, sepal width, petal length, and petal width for 150 iris flowers across three species.

 
# Setup code for iris dataset
import statsmodels.api as sm
import pandas as pd
from scipy import stats
import numpy as np

# Load iris dataset from statsmodels 
iris = sm.datasets.get_rdataset('iris').data

# Separate species for group comparisons
setosa = iris[iris['Species'] == 'setosa']['Sepal.Length']
versicolor = iris[iris['Species'] == 'versicolor']['Sepal.Length']
virginica = iris[iris['Species'] == 'virginica']['Sepal.Length']

1. One-Sample T-Test

 
stats.ttest_1samp(iris['Sepal.Length'], 5.5)

Output:

 
TtestResult(statistic=5.0780453996425345, pvalue=1.12311195083408e-06, df=149)

The one-sample t-test examines whether the mean of a sample differs significantly from a hypothesized value. Here, we test if the average sepal length differs from 5.5 cm. With a p-value of 1.12e-06 (essentially zero), we can confidently reject the null hypothesis. The positive t-statistic (5.078) indicates the actual mean is significantly higher than 5.5 cm – it’s actually around 5.84 cm.

2. Independent T-Test

 
stats.ttest_ind(setosa, versicolor)

Output:

 
Ttest_indResult(statistic=-10.52098626754911, pvalue=8.985235037487079e-18)

This independent samples t-test compares sepal lengths between two species. The dramatically negative t-statistic (-10.52) tells us that setosa flowers have significantly shorter sepals than versicolor flowers. The p-value (8.98e-18) is practically zero, indicating an extremely significant difference. This makes biological sense, as different iris species have distinct morphological characteristics.

3. Shapiro-Wilk Normality Test

 
stats.shapiro(iris['Sepal.Length'])

Output:

 
ShapiroResult(statistic=0.9760899543762207, pvalue=0.01018026564270258)

The Shapiro-Wilk test assesses whether data follows a normal distribution. The test statistic (0.976) is close to 1, which would indicate perfect normality. However, the p-value (0.0102) suggests a significant departure from normality at the 0.05 level. With a large sample size like ours (n=150), even small deviations from normality can reach statistical significance, though they may not be practically important for most analyses.

4. One-Way ANOVA

 
stats.f_oneway(setosa, versicolor, virginica)

Output:

 
F_onewayResult(statistic=119.26450218450468, pvalue=1.6696691907693826e-31)

The one-way ANOVA tests whether three or more groups have significantly different means. Our massive F-statistic (119.26) and microscopic p-value (1.67e-31) provide overwhelming evidence that the three iris species have different average sepal lengths. This test sets the stage perfectly for follow-up analyses to determine which specific species differ from each other.

SciPy’s approach gives us exactly what we need: clean test statistics and p-values without information overload. These functions are perfect for quick hypothesis testing and exploratory analysis. However, when we need more detailed output or want to build complex models, we need to reach for more specialized tools.

Building Complex Models with Statsmodels

While SciPy excels at basic hypothesis testing, Statsmodels shines when you need comprehensive statistical modeling with detailed output. Using R-style formulas, Statsmodels makes it easy to specify complex relationships between variables and provides academic-quality results that include everything from coefficient estimates to diagnostic tests.

For these examples, we’ll switch to the tips dataset, which contains information about restaurant bills, tips, and customer characteristics. This dataset is perfect for demonstrating regression analysis and ANOVA with categorical predictors.

 
# Setup code for tips dataset  
import statsmodels.api as sm
import statsmodels.formula.api as smf
import pingouin as pg
import seaborn as sns
import pandas as pd

# Load tips dataset
tips = sns.load_dataset('tips')

5. Linear Regression

 
smf.ols('tip ~ total_bill', data=tips).fit().summary()

OLS regression results showing total_bill significantly predicts tip amount, with R-squared of 0.457.
Image By Author
 

This one-liner creates an ordinary least squares regression model predicting tip amount from total bill. The R-style formula syntax (tip ~ total_bill) makes the relationship crystal clear. Statsmodels returns a comprehensive summary table showing that the total bill explains 45.7% of tip variation (R-squared = 0.457). The coefficient of 0.105 means that for every dollar increase in the bill, tips increase by about 10.5 cents on average. With an F-statistic of 203.4 and p-value near zero, this relationship is highly significant.

6. Multiple Regression with Categorical Variables

 
smf.ols('tip ~ total_bill + sex + smoker + day', data=tips).fit().summary()

OLS regression including categorical predictors like sex, smoker status, and day shows total_bill remains the only significant predictor.
Image By Author
 

Building on our simple regression, this model includes categorical predictors like customer sex, smoking status, and day of the week. Statsmodels automatically handles the dummy variable encoding for categorical variables. Interestingly, adding these variables barely improves the model (R-squared increases only to 0.461), and none of the categorical variables are statistically significant. This demonstrates an important lesson: more complex models don’t always perform better, and the total bill remains the dominant predictor of tip amount.

7. Two-Way ANOVA

 
smf.ols('tip ~ sex * smoker', data=tips).fit().summary()

OLS regression examining interaction between sex and smoker shows no significant effects; model explains very little variance.
Image By Author
 

This two-way ANOVA examines how sex and smoking status affect tips, including their interaction (denoted by the * in the formula). The results tell a different story than our regression models: without the total bill as a covariate, these categorical variables explain very little variance (R-squared = 0.009). None of the main effects or interactions reach statistical significance (F-statistic = 0.75, p = 0.523). This highlights how including a continuous covariate can dramatically change our conclusions about categorical effects.

Statsmodels excels at providing detailed output that academic researchers and statisticians expect. Every model includes goodness-of-fit statistics, diagnostic tests, and confidence intervals. However, sometimes this wealth of information can be overwhelming, especially for quick analyses or when you want a cleaner, more modern interface.

Modern Statistics with Pingouin

Pingouin represents the next generation of statistical computing in Python, designed to bridge the gap between SciPy’s simplicity and Statsmodels’ comprehensiveness. It provides clean, readable output with automatic inclusion of effect sizes, confidence intervals, and modern statistical measures like Bayes factors. Best of all, it maintains the same dataset (tips) for easy comparison with our Statsmodels examples.

8. Enhanced Linear Regression Output

 
pg.linear_regression(tips[['total_bill']], tips['tip'])

Summary table of coefficients and confidence intervals from a simple regression model using total_bill.
Image By Author
 

Pingouin’s regression output offers the same core results as Statsmodels but comes with few enhancements. Notice how it automatically includes confidence intervals for each coefficient and presents everything in a clean, easily readable DataFrame format. The results confirm our earlier findings: the total bill coefficient is 0.105 with a 95% confidence interval of [0.091, 0.120]. This tabular format makes it much easier to extract specific values programmatically or share results in reports compared to Statsmodels’ verbose text output.

9. ANOVA with Effect Size

 
pg.anova(data=tips, dv='tip', between='day')

One-way ANOVA results testing tip differences across days of the week show no significant effect.
Image By Author
 

Here’s where Pingouin truly shines: it automatically calculates and reports effect sizes alongside traditional statistics. The partial eta-squared (np2 = 0.0205) tells us that day of the week explains only about 2% of the variance in tips – a small effect size. The ANOVA syntax is also more intuitive than Statsmodels’ regression approach, using explicit dv (dependent variable) and between parameters that make the analysis intent crystal clear.

10. Pairwise T-Tests with Correction

 
pg.pairwise_tests(data=tips, dv='tip', between='day', padjust='bonf')

Post-hoc comparisons between days of the week; no pairwise differences remain significant after correction.
Image By Author
 

This final one-liner demonstrates Pingouin’s most impressive feature: comprehensive post-hoc analysis in a single function call. After finding a non-significant ANOVA, these pairwise comparisons reveal that even individual day comparisons show weak evidence for differences. The table includes uncorrected p-values, Bonferroni-corrected p-values, Bayes factors (BF10), and Hedges’ g effect sizes. The Bayes factors mostly favor the null hypothesis (values < 1), suggesting minimal differences between days. This level of analysis would require several lines of code in other libraries.

Summary

These 10 one-liners illustrate the evolution of statistical computing in Python:

  1. SciPy provides the essentials – clean test statistics and p-values perfect for quick hypothesis testing and exploratory analysis.
  2. Statsmodels offers comprehensive academic-style output with detailed regression tables, diagnostic tests, and flexible formula syntax ideal for formal statistical modeling.
  3. Pingouin combines the best of both worlds with clean, informative output that includes modern statistical measures like effect sizes and Bayes factors, making it perfect for contemporary data analysis workflows.

Each library has its place in the data analyst’s toolkit. Start with SciPy for basic tests, use Statsmodels when you need detailed output or complex models, and reach for Pingouin when you want modern statistical analysis with minimal code. Choose based on your analysis goals: quick exploration, comprehensive modeling, or modern statistical reporting.

Leave a Reply

Your email address will not be published. Required fields are marked *