Loading...

Pingouin

Statistical package for Python focused on ease of use and readable output for common statistical tests

Advanced Data Analysis & Machine Learning Intermediate Recommended Tool
Quick Info
  • Category: Advanced Data Analysis & Machine Learning
  • Level: Intermediate
  • Type: Recommended Tool
  • Requires:

Why We Recommend Pingouin

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.

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
Top