Skip to main content

A unified, self-contained statistical analysis library for Python -- an SPSS/R replacement.

Reason this release was yanked:

updated

Project description

SPSSMirror

PyPI version Python versions License: MIT

SPSSMirror is a unified, self-contained statistical analysis library for Python — a modern SPSS/R replacement. Every method wraps scipy/statsmodels/scikit-learn/lifelines/pymc/arch internally and returns a typed, immutable result object with the statistic, p-value, effect size, and confidence interval already computed. You never need to import those libraries yourself to get a complete answer.

from spssmirror import SPSSMirror

mirror = SPSSMirror().load_csv("survey.csv")
result = mirror.regression().linear("score ~ age + C(group)")
print(result.r_squared, result.coefficients)

Table of contents


Why SPSSMirror

Most Python statistics work means juggling scipy.stats, statsmodels, scikit-learn, and reading each library's own conventions for what a "result" looks like. SPSSMirror collapses that into one consistent API:

  • One object per analysis. mirror.frequentist().t_test_independent(...) returns a StatTestResult with .statistic, .p_value, .effect_size, and .data_quality — every method across every engine follows the same shape.
  • Honest about uncertainty. Regularized regression (Ridge/Lasso) reports std_error/p_value as None instead of fabricating classical inference that regularization invalidates. A mixed model fit with REML reports aic/bic as None rather than silently leaking statsmodels' NaN.
  • Refuses to compute nonsense. Running an ANOVA or regression on a column that turns out to be constant raises a clear error instead of a false "p = 0.000016, significant!" result caused by floating-point noise in the underlying model fit.
  • Every result tracks its own data qualityn_rows_original, n_nulls_dropped, max_missing_ratio — so you always know what was silently dropped before you trust a number.
  • Formula syntax where it belongs. Regression, the ANOVA family, mixed models, and residual diagnostics accept R-like formulas via patsy: "y ~ x1 + C(group) * x2".

Installation

pip install spssmirror

This installs the core engine — descriptive statistics, regression, the full frequentist test suite (parametric and non-parametric), categorical analysis, correlations, psychometrics, effect sizes, power analysis, diagnostics, and mixed models — with a deliberately lean dependency list (pandas, numpy, scipy, statsmodels, pydantic, patsy, rapidfuzz, factor_analyzer).

Four engines depend on heavier, optional libraries and are installed as extras:

pip install spssmirror[bayesian]      # Bayesian t-test/regression (pymc, arviz)
pip install spssmirror[timeseries]    # ARIMA/GARCH forecasting (arch)
pip install spssmirror[survival]      # Kaplan-Meier / Cox PH (lifelines)
pip install spssmirror[multivariate]  # PCA / clustering / discriminant (scikit-learn)
pip install spssmirror[all]           # everything at once

The core install works with zero optional dependencies present — verified by installing the built wheel into a clean virtual environment as part of the test process.

What's included

Engine Access Methods
Descriptive .descriptive() summary, frequency_table, crosstab
Regression .regression() linear, logistic, poisson, glm, robust, ridge, lasso, elastic_net
Frequentist (parametric) .frequentist() t_test_one_sample, t_test_independent, t_test_paired, anova_oneway, anova_twoway, ancova, anova_repeated_measures, manova
Frequentist (non-parametric) .nonparametric() mann_whitney_u, wilcoxon_signed_rank, kruskal_wallis, friedman_test
Categorical .categorical() chi_square_independence, fishers_exact, mcnemar_test
Correlation .correlations() pearson, spearman, kendall_tau, point_biserial, partial, correlation_matrix
Psychometrics .psychometrics() cronbach_alpha, mcdonald_omega, split_half, kmo, bartlett_sphericity, item_analysis, efa
Effect sizes .effect_sizes() cohens_d, hedges_g, glass_delta, eta_squared, omega_squared, cramers_v, odds_ratio
Power analysis .power() power_ttest_independent, power_ttest_paired, power_ttest_one_sample, power_anova, power_correlation, power_chisquare, power_curve_ttest, power_curve_anova, power_curve_correlation
Diagnostics .diagnostics() normality_tests, homogeneity_of_variance, vif, residual_diagnostics, outliers
Mixed models .mixed_models() linear_mixed_model (random intercept/slope, ICC)
Bayesian (extra) .bayesian() bayesian_ttest, bayesian_proportion_test, bayesian_linear_regression
Time series (extra) .timeseries() arima, auto_arima, exponential_smoothing, garch, acf_pacf, stationarity_test
Survival (extra) .survival() kaplan_meier, logrank_test, cox_ph, parametric_survival
Multivariate (extra) .multivariate() pca, kmeans_clustering, hierarchical_clustering, linear_discriminant, quadratic_discriminant, canonical_correlation

Every method returns a frozen Pydantic model. Inspect fields directly, or call .model_dump() / .model_dump_json() to export.

Quick start

from spssmirror import SPSSMirror

mirror = SPSSMirror().load_csv("data.csv")

# Reliability
alpha = mirror.psychometrics().cronbach_alpha(["q1", "q2", "q3", "q4"])
print(alpha.statistic)

# Group comparison with effect size
t = mirror.frequentist().t_test_independent("score", "group", "A", "B")
print(t.statistic, t.p_value, t.effect_size)

# Regression — no statsmodels import needed anywhere in your code
reg = mirror.regression().linear("outcome ~ predictor1 + C(category)")
for coef in reg.coefficients:
    print(coef.term, coef.b, coef.p_value)

# Power analysis
power = mirror.power().power_ttest_independent(effect_size=0.5, alpha=0.05, power=0.80)
print(f"Need {power.n:.0f} participants per group")

Loading data:

SPSSMirror().load_csv("data.csv")
SPSSMirror().load_excel("data.xlsx")
SPSSMirror().load_dict({"col1": [...], "col2": [...]})
SPSSMirror().load_dataframe(existing_pandas_df)

Design principles

  1. Nothing leaks. Public methods never return a raw scipy/statsmodels/scikit-learn/pymc/lifelines/arch object — only SPSSMirror's own typed models.
  2. Honest statistics over convenient statistics. If a number can't be computed validly, the field is None, not a fabricated or silently wrong value.
  3. Data quality is never hidden. Every result that drops rows (nulls, non-finite values) reports exactly how many and what fraction.
  4. No visualization dependency. Results are plain, inspectable data — pair with whatever plotting library your project already uses.

Testing

git clone https://github.com/<your-username>/spssmirror.git
cd spssmirror
pip install -e ".[all,dev]"
pytest tests/ -v

The test suite checks every engine against engineered ground truth (known true effects and known coefficients, not just "does it run") — see tests/conftest.py for the fixtures.

Contributing

Issues and pull requests are welcome. Please include a test demonstrating the bug or feature — see tests/ for the existing pattern (each test targets one method against either a known analytical result or a clearly engineered scenario).

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spssmirror-2.0.1.tar.gz (53.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spssmirror-2.0.1-py3-none-any.whl (59.1 kB view details)

Uploaded Python 3

File details

Details for the file spssmirror-2.0.1.tar.gz.

File metadata

  • Download URL: spssmirror-2.0.1.tar.gz
  • Upload date:
  • Size: 53.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for spssmirror-2.0.1.tar.gz
Algorithm Hash digest
SHA256 c3c539550d3aee0aa934cad35366c627a052f1e65167fe85a48cd9c5f1057a06
MD5 c3776e341abd4855210147bc051ba32a
BLAKE2b-256 2c8ee27a486171e159cc63330df574e01c2694b5f8023b89bd0e75263668f4b2

See more details on using hashes here.

File details

Details for the file spssmirror-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: spssmirror-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 59.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for spssmirror-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 13a26d0298cba88d29681ac633db43fc211afb3e1eff32bc6a0566e97df97f08
MD5 b6397d598cae9137bc636d3e5821ac78
BLAKE2b-256 7a6eb5f6e02bed5ff02c37a468b8d116ef2a0406fe988f09126d7d4bf9426077

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page