Pingouin
Statistical package for Python focused on ease of use and readable output for common statistical tests
Our View
Pingouin provides a simple, consistent interface for statistical testing that produces readable output. It's perfect for researchers who need to run standard statistical tests without getting lost in complex API documentation, and it integrates beautifully with pandas DataFrames.
Provisional positions are editorial proposals awaiting group review.
Teaching — Recorded in topic offerings; consult the dated event links for availability.
2 topics with recorded teaching · 10 past offerings · 0 upcoming offerings
Related themes: Scientific Computing
Related topics: Arrays and Numerical ComputingDataframes and Statistics
Common use cases
- T-tests and ANOVA analyses
- Correlation and regression analysis
- Effect size calculations
- Pairwise comparisons with correction
Getting started
Pingouin is an open-source statistical package for Python that provides simple, readable functions for common statistical tests. It’s designed to be user-friendly while maintaining statistical rigor.
Why Pingouin?
- Readable Output: Results returned as pandas DataFrames
- Effect Sizes: Automatically calculates effect sizes
- Simple API: Consistent, intuitive function names
- Comprehensive: Covers most common statistical tests
- Well-Documented: Clear examples and explanations
Basic T-Tests
Independent Samples T-Test
import pingouin as pg
import pandas as pd
# Independent t-test
result = pg.ttest(
control_group['reaction_time'],
treatment_group['reaction_time'],
correction='auto' # Welch's t-test if unequal variances
)
print(result)
# Returns DataFrame with: T, dof, alternative, p-val, CI95%, cohen-d, BF10, power
Paired T-Test
# Paired samples (e.g., pre/post measurements)
result = pg.ttest(
df['pre_score'],
df['post_score'],
paired=True
)
One-Sample T-Test
# Test against a value (e.g., chance level)
result = pg.ttest(df['accuracy'], 0.5) # Test if accuracy > 50%
ANOVA
One-Way ANOVA
# One-way ANOVA
aov = pg.anova(
data=df,
dv='reaction_time', # Dependent variable
between='condition' # Independent variable
)
print(aov)
# Returns: Source, SS, DF, MS, F, p-unc, np2 (effect size)
Repeated Measures ANOVA
# Within-subjects ANOVA
aov = pg.rm_anova(
data=df,
dv='performance',
within='time_point',
subject='subject_id'
)
Two-Way ANOVA
# Two factors
aov = pg.anova(
data=df,
dv='score',
between=['treatment', 'gender']
)
Mixed ANOVA
# Mixed design (between + within factors)
aov = pg.mixed_anova(
data=df,
dv='response',
within='session',
subject='subject_id',
between='group'
)
Post-Hoc Tests
Pairwise Comparisons
# Post-hoc pairwise tests with multiple comparison correction
posthoc = pg.pairwise_tests(
data=df,
dv='score',
between='condition',
padjust='fdr_bh' # Benjamini-Hochberg FDR correction
)
print(posthoc)
# Shows all pairwise comparisons with corrected p-values
Tukey HSD
# Tukey's Honestly Significant Difference
tukey = pg.pairwise_tukey(
data=df,
dv='reaction_time',
between='condition'
)
Correlation Analysis
Pearson Correlation
# Pearson correlation
r = pg.corr(df['variable1'], df['variable2'])
print(r)
# Returns: n, r, CI95%, p-val, BF10, power
Spearman Correlation
# Non-parametric correlation
rho = pg.corr(df['var1'], df['var2'], method='spearman')
Partial Correlation
# Control for confounding variable
partial = pg.partial_corr(
data=df,
x='brain_activity',
y='behavior',
covar='age' # Control for age
)
Correlation Matrix
# Pairwise correlations for multiple variables
corr_matrix = pg.pairwise_corr(
df[['var1', 'var2', 'var3', 'var4']],
method='pearson'
)
Effect Sizes
Cohen’s d
# Effect size for t-test
d = pg.compute_effsize(
control_data,
treatment_data,
eftype='cohen'
)
# Or use hedges (corrected for small samples)
hedges_g = pg.compute_effsize(
control_data,
treatment_data,
eftype='hedges'
)
Confidence Intervals
# Bootstrap confidence interval
ci = pg.compute_bootci(
data,
func=np.mean,
n_boot=5000,
confidence=0.95
)
Normality and Assumptions
Test Normality
# Shapiro-Wilk test
normal, pval = pg.normality(df, dv='reaction_time', group='condition')
Test Homoscedasticity
# Levene's test for equal variances
equal_var, pval = pg.homoscedasticity(df, dv='score', group='condition')
Sphericity Test
# Mauchly's test for repeated measures
spher, W, chi2, dof, pval = pg.sphericity(
data=df,
dv='response',
subject='subject_id',
within='time'
)
Non-Parametric Tests
Mann-Whitney U Test
# Non-parametric alternative to t-test
result = pg.mwu(group1_data, group2_data)
Wilcoxon Signed-Rank Test
# Non-parametric paired test
result = pg.wilcoxon(pre_data, post_data)
Kruskal-Wallis Test
# Non-parametric alternative to ANOVA
result = pg.kruskal(
data=df,
dv='score',
between='condition'
)
Practical Neuroscience Examples
Calcium Imaging Analysis
import pingouin as pg
# Compare neural responses between conditions
aov = pg.anova(
data=neural_df,
dv='dF_F',
between='stimulus_type'
)
# Post-hoc comparisons
posthoc = pg.pairwise_tests(
data=neural_df,
dv='dF_F',
between='stimulus_type',
padjust='bonf'
)
# Effect sizes
effect_size = pg.compute_effsize(
neural_df[neural_df['stimulus'] == 'A']['dF_F'],
neural_df[neural_df['stimulus'] == 'B']['dF_F'],
eftype='cohen'
)
Behavioral Experiment Analysis
# Repeated measures ANOVA for learning over sessions
learning_aov = pg.rm_anova(
data=behavior_df,
dv='accuracy',
within='session',
subject='subject_id'
)
# Correlation between behavior and neural activity
correlation = pg.corr(
behavior_df['reaction_time'],
neural_df['peak_response']
)
Multi-Condition Comparison
# Compare firing rates across multiple brain regions
regions_aov = pg.anova(
data=ephys_df,
dv='firing_rate',
between='region'
)
# Pairwise comparisons with FDR correction
pairwise = pg.pairwise_tests(
data=ephys_df,
dv='firing_rate',
between='region',
padjust='fdr_bh'
)
# Check which comparisons are significant
significant = pairwise[pairwise['p-corr'] < 0.05]
Working with DataFrames
# Pingouin works seamlessly with pandas
df = pd.DataFrame({
'subject': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'condition': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
'score': [10, 12, 14, 11, 13, 15, 9, 11, 13]
})
# Run analysis
result = pg.rm_anova(
data=df,
dv='score',
within='condition',
subject='subject'
)
# Results are pandas DataFrames - easy to save or process
result.to_csv('anova_results.csv')
Bayesian Statistics
# Bayesian t-test
result = pg.ttest(control, treatment, correction=False)
# Result includes BF10 (Bayes Factor)
# Interpret Bayes Factor
if result['BF10'].values[0] > 3:
print("Moderate evidence for alternative hypothesis")
elif result['BF10'].values[0] < 1/3:
print("Moderate evidence for null hypothesis")
Power Analysis
# Compute statistical power
power = pg.power_ttest(
d=0.5, # Effect size
n=30, # Sample size
alpha=0.05
)
# Or determine required sample size
n = pg.power_ttest(
d=0.5,
power=0.8,
alpha=0.05
)
Installation
pixi add pingouin
# or
conda install -c conda-forge pingouin
# or
pip install pingouin
Best Practices
- Always check assumptions (normality, homoscedasticity) before parametric tests
- Use FDR correction for multiple comparisons
- Report effect sizes along with p-values
- Consider Bayesian alternatives (BF10) for ambiguous results
- Visualize data before running statistical tests
- Save results as CSV for reproducibility
- Use paired tests when data is related (pre/post, matched subjects)
- Check power analysis for adequate sample sizes