import greenwood as gw
# Load data and represent it as a survival object
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
ySurv(type=right, n=228, events=165)
Modern survival analysis for Python: Narwhals-native, R-validated, beautifully visualized.
Contributing guide
Code of conduct
Project roadmap
Security policy
Full license MIT
Citing greenwood
Requires: Python >=3.10
Provides-Extra: pd, pl, pa, formula, plotnine, altair, tables, fast, all, dev, docs
Package Info
Greenwood turns time-to-event data into estimates, tests, models, and figures. Whether you’re tracking patient outcomes, equipment failure times, or any event that takes time to happen, Greenwood provides a complete, production-ready toolkit for survival analysis.
Unlike many statistical libraries, Greenwood is built on Narwhals for backend-agnostic compute, validated to tolerance against R’s gold-standard survival package, and visualized with publication-quality interactive plots and tables. It works with Pandas, Polars, PyArrow, or any dataframe library you prefer.
format= argument to control output types).Every Greenwood analysis follows a consistent workflow:
forest_plot, or cif_plot, and assess model performance with concordance, Brier scores, or cross-validation.Here’s a complete example: load survival data, estimate a curve, test for differences, and visualize.
Step 1: Represent the data with a Surv object
import greenwood as gw
# Load data and represent it as a survival object
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
ySurv(type=right, n=228, events=165)
Step 2: Estimate Kaplan-Meier survival curves, stratified by sex
# Fit stratified Kaplan-Meier with log-log confidence intervals
km = gw.KaplanMeier(conf_type="log-log").fit(y, by=lung["sex"])
# Get median survival per group with 95% confidence intervals
km.median(ci=True){1: (270.0, 210.0, 306.0), 2: (426.0, 345.0, 524.0)}
Step 3: Compare survival between groups with a log-rank test
# Test for differences in survival between sexes
test_result = gw.logrank_test(y, group=lung["sex"])
test_resultTestResult(method='Log-rank test', statistic=10.3267, df=1, p_value=0.001311)
Step 4: Visualize with an interactive plot and at-risk table
Step 5: Fit a Cox proportional hazards model
# Model covariate effects on hazard
cox = gw.CoxPH().fit(y, lung[["age", "sex"]])
# Get hazard ratios with confidence intervals
gw.tidy(cox, exponentiate=True, format="polars")| term | estimate | std_error | statistic | p_value | conf_low | conf_high |
|---|---|---|---|---|---|---|
| str | f64 | f64 | f64 | f64 | f64 | f64 |
| "age" | 1.017191 | 0.009223 | 1.848078 | 0.064591 | 0.998969 | 1.035747 |
| "sex" | 0.598566 | 0.167458 | -3.06476 | 0.002178 | 0.431094 | 0.831099 |
Descriptive statistics: Kaplan-Meier curves with Greenwood confidence intervals, restricted mean survival time (RMST), quantiles, and medians. Nelson-Aalen cumulative hazard. Event tables and risk sets.
Group comparisons: Log-rank and Peto-Peto tests, Fleming-Harrington tests for weighted comparisons, linear trend tests across ordered groups, and RMST hypothesis tests with pairwise comparisons.
Regression models: Cox proportional hazards with stratification, baseline hazard prediction with confidence intervals, and full diagnostics. Parametric accelerated failure time (AFT) models with Weibull, exponential, log-normal, and log-logistic distributions. Competing risks via Aalen-Johansen and Fine-Gray models. Multi-state transition probabilities.
Visualization: interactive survival curves with confidence bands, censoring marks, and aligned at-risk tables. Forest plots with hazard ratios. Cumulative incidence plots for competing risks. All plots are interactive and publication-ready.
Model evaluation: Concordance index (Harrell’s C-statistic), IPCW Brier scores, integrated Brier scores, and k-fold cross-validation with stratification support.
Built-in data: load bundled datasets (lung, veteran, ovarian, pbc, colon, mgus2) in any supported backend.
pip install greenwood or see Installation.| ✓ Narwhals-native for dataframe agility | ✓ R-validated for trustworthy results |
| ✓ Interactive publication plots | ✓ Great Tables integration |
| ✓ Complete toolkit (KM to competing risks) | ✓ Broom-compatible tidy outputs |
| ✓ Built-in datasets and R parity tests | ✓ Cross-validation with stratification |