Skip to content

stratindex

A nonparametric index of stratification (Zhou 2012) — a Python port of the R package strat by Xiang Zhou.

The index measures how strongly a set of strata (social classes, occupations, schools, …) stratifies a numeric outcome (income, test scores, …). It is the weighted excess of concordant over discordant pairs among all pairs of observations drawn from different strata with distinct outcomes — an analogue of Somers' D where strata are ordered by the average percentile rank of their members (or taken as pre-ordered). The index lies in [-1, 1]: 1 means perfect stratification, 0 means no stratification.

Zhou, Xiang. 2012. "A Nonparametric Index of Stratification." Sociological Methodology, 42(1): 365–389. doi:10.1177/0081175012452207

Installation

pip install stratindex

Requires Python ≥ 3.12; the only runtime dependency is NumPy.

Quick start

from stratindex import strat, srank, load_cpsmarch2015

d = load_cpsmarch2015()  # bundled example data: March CPS 2015, 14,358 men

# stratum-specific information: population share and average percentile rank
print(srank(d, outcome="income", strata="big_class", weights="weight"))

# the stratification index with a between-/within-group decomposition
s = strat(d, outcome="income", strata="big_class",
          weights="weight", group="education")
print(s.format(digits=4))
overall stratification:

 strat  std_error
0.4128    0.01296

decomposition by education:

                   weight   strat
 within education  0.2435  0.2684
between education  0.7565  0.4592

The first argument may be a pandas DataFrame or any mapping of columns; plain array calls — strat(income, big_class, weights=w) — work the same way. pandas Categorical strata keep their category order (used by ordered=True and for row order in the tables).

Standard errors

By default the standard error is the Goodman & Kruskal (1963) approximation, as in the R package. A bootstrap alternative recomputes percentile ranks and stratum ordering in every replicate:

strat(d, outcome="income", strata="big_class", weights="weight",
      se_method="bootstrap", n_boot=500, random_state=0)

Correspondence with the R package

R Python
strat(outcome, strata, weights, ordered, group) strat(outcome, strata, weights=None, ordered=False, group=None, group_name=None)
srank(outcome, strata, weights, group) srank(outcome, strata, weights=None, group=None)
s$overall (strat, std_error) s.strat, s.std_error (or s.overall)
s$strata_info s.strata_info
s$decomposition s.decomposition
s$within_group s.within_group
data(cpsmarch2015) load_cpsmarch2015()

Numerical output is cross-validated against the original R package: golden values generated by CRAN strat are part of the test suite, and a CI job regenerates them from CRAN on every push.

License

GPL-3.0-or-later, same as the original R package (this is a derivative work).