AFT

Parametric accelerated failure time model.

Usage

Source

AFT(
    dist="weibull",
    *,
    conf_level=0.95,
    method="mle",
    threshold=False,
)

While the Cox proportional hazards model leaves the baseline hazard unspecified, AFT models assume a fully parametric distribution for survival times and model how covariates accelerate or decelerate the “clock” of failure. Specifically, \log(T) = \mu + \beta^\top x + \sigma\varepsilon, where T is survival time, \beta are log-time-scale coefficients, \sigma is a scale parameter, and \varepsilon follows a specified error distribution (e.g., extreme-value, logistic, normal). This means a unit increase in covariate x multiplies survival time by \exp(\beta).

AFT models are useful when you want explicit, interpretable survival time predictions or when the parametric assumptions are reasonable. Unlike Cox models, they require choosing a distributional family (Weibull, exponential, lognormal, or loglogistic). Call fit() with a right-censored Surv response and a design matrix. The model automatically adds an intercept and estimates coefficients (on the log-time scale), the scale parameter, and standard errors via maximum likelihood.

The implementation uses numerical optimization (typically Newton-Raphson) to maximize the likelihood. Coefficients on the log-time scale can be exponentiated to obtain time-acceleration ratios: \exp(\beta) is the multiplicative effect on median or mean survival. The model also supports prediction of survival probabilities and quantiles at future times given covariate values.

Parameters

dist: str = "weibull"

Error distribution: "weibull" (default), "exponential", "lognormal", "loglogistic", or "gengamma" (generalized gamma). The generalized gamma encompasses Weibull and log-normal as special cases, making it useful for distribution selection via likelihood ratio tests (see test_distributions()).

conf_level: float = 0.95

Confidence level for coefficient intervals (the default is 0.95).

method: str = "mle"

Estimation method: "mle" (default, ordinary maximum likelihood) or "mps" (maximum product of spacings). MPS replaces each exact observation’s density contribution with the gap between consecutive order statistics on the CDF scale, which stays bounded where MLE’s density can diverge; see threshold for when this matters.

threshold: bool = False
If True, fit a three-parameter model with a location/threshold parameter \gamma: T = \gamma + T', where T' follows the ordinary 2-parameter dist. Not supported for dist="gengamma". method="mle" with threshold=True can drive \gamma toward the smallest observed time, where the likelihood is unbounded for some distributions; method="mps" is recommended in that case (a warning is raised otherwise).

Returns

Fitted estimator
Call fit() to produce a fitted estimator with cached results (coef_, scale_, threshold_, std_error_, z_, p_value_, conf_low_, conf_high_, loglik_, aic_, bic_), accessible as arrays or exported to DataFrames.

Details

Call fit(surv, covariates) with a right-censored Surv response and a covariate design (a 2-D array or a dataframe). An intercept is added automatically; rows with missing covariates are dropped. Results are exposed as arrays (coef_, scale_, std_error_, z_, p_value_) and as tidy frames via to_frame() (optionally format=) and greenwood.tidy.

Examples

Build a Surv response from the bundled lung dataset and fit a Weibull AFT model with age and sex as covariates. Printing the fitted object reports the coefficients (on the log-time scale), the scale, and the log-likelihood.

import greenwood as gw

# Load data and build a right-censored response
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))

# Fit a Weibull AFT model with age and sex as covariates
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])
aft
AFT (accelerated failure time model, dist='weibull')

                 coef  se(coef)       z         p
(Intercept)     6.275    0.4814  13.036  7.65e-39
age          -0.01226  0.006957  -1.762    0.0781
sex            0.3821    0.1275   2.997  0.002723

Scale = 0.7541
n = 228, events = 165
Log-likelihood = -1147

Methods

Name Description
fit() Fit the accelerated failure time model to survival data.
predict() Predict survival times, quantiles, or survival probabilities from the AFT model.
predict_expectation() Predict the expected (restricted mean) survival time for each subject.
predict_median() Predict the median survival time for each subject.
predict_quantile() Predict survival-time quantiles for each subject.
residuals() Return diagnostic residuals from the fitted AFT model.
test_distributions() Compare the generalized gamma fit against nested sub-models.
to_frame() Return the coefficient table as a DataFrame.

fit()

Fit the accelerated failure time model to survival data.

Usage

Source

fit(
    surv,
    covariates,
    *,
    data=None,
)

Fits a parametric accelerated failure time (AFT) model to a right-censored response and covariates. The AFT models the log-survival time as a linear regression on covariates plus a random error from a specified parametric distribution (Weibull, exponential, log-normal, or log-logistic). An intercept is added automatically.

The AFT is a parametric alternative to Cox regression, providing a fully specified survival distribution at the cost of stronger distributional assumptions. Unlike Cox, AFT supports median survival predictions and is naturally interpreted on the log-time scale: a coefficient of 0.1 means the covariate multiplies survival time by \exp(0.1). Results are stored in the fitted object as coefficient arrays and can be exported to DataFrames.

Parameters

surv: Surv

A right-censored Surv response. Built with Surv.right(). Interval-censored or other response types raise NotImplementedError.

covariates: Any

A dataframe (pandas or polars), a 2-D array, or a formula string (e.g., "age + sex") evaluated against the data argument.

data: Any = None
A dataframe to evaluate the formula string (ignored if covariates is a dataframe or array).

Returns

AFT
The fitted estimator object itself (for method chaining) with cached coefficient arrays (coef_, std_error_, z_, p_value_), scale parameter (scale_), threshold (threshold_, 0.0 unless threshold=True), and log-likelihood (loglik_).

Details

The AFT model parameterizes log-survival time as \log(T) = X\beta + \sigma\varepsilon, where X is the design matrix, \beta are coefficients, \sigma is a scale parameter, and \varepsilon is an error term from the chosen distribution. The survival function is then S(t \mid X) = P(T > t \mid X) = G((\log(t) - X\beta) / \sigma), where G is the survival function of the error distribution.

Estimation uses maximum likelihood via numerical optimization by default (method="mle"). Exponential and Weibull models are nested special cases; log-normal and log-logistic offer different tail behaviors. With threshold=True, T = \gamma + T' for a location parameter \gamma \ge 0 and 2-parameter dist T'; method="mps" (maximum product of spacings) replaces each exact observation’s density with the gap between consecutive order statistics on the CDF scale, which stays bounded where the ordinary likelihood can diverge as \gamma approaches the smallest observed time.

Examples

Fit a log-normal AFT model on the bundled lung dataset with age and sex as covariates:

import greenwood as gw

# Load data and build a right-censored response
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))

# Fit a log-normal AFT model
aft = gw.AFT(dist="lognormal").fit(y, lung[["age", "sex"]])
aft
AFT (accelerated failure time model, dist='lognormal')

                 coef  se(coef)       z          p
(Intercept)     6.408    0.5929  10.808  3.152e-27
age          -0.02336  0.008388  -2.785   0.005359
sex            0.5193    0.1551   3.347  0.0008175

Scale = 1.053
n = 228, events = 165
Log-likelihood = -1159

Use a formula string with the data= argument:

# Fit via a formula string instead of a DataFrame
aft_formula = gw.AFT(dist="weibull").fit(y, "age + sex", data=lung)
aft_formula
AFT (accelerated failure time model, dist='weibull')

                 coef  se(coef)       z         p
(Intercept)     6.275    0.4814  13.036  7.65e-39
age          -0.01226  0.006957  -1.762    0.0781
sex            0.3821    0.1275   2.997  0.002723

Scale = 0.7541
n = 228, events = 165
Log-likelihood = -1147

predict()

Predict survival times, quantiles, or survival probabilities from the AFT model.

Usage

Source

predict(
    newdata=None,
    *,
    type="survival",
    times=None,
    p=0.5,
    tau=None,
    conditional_after=None,
    ci=False,
    conf_type="log-log",
    format=None,
)

Generates predictions from a fitted accelerated failure time model. The AFT is a fully parametric survival model, so predictions require specifying both the predictor values (via newdata=) and the type of prediction desired. Pass newdata=None to predict for the training data (fitted subjects).

Six prediction types are available:

  1. Linear predictor (type="lp"): the log-time location X\beta, showing how covariates shift the log-survival time distribution.

  2. Quantile (type="quantile"): predicted survival-time quantiles at specified failure probabilities (e.g., median survival when p=0.5). Useful for clinical summaries like “50% of subjects with these covariates survive to time X.”

  3. Survival (type="survival"): survival probabilities S(t \mid x) at specified times, returned as a DataFrame for easy visualization. Optionally condition on already having survived to a landmark time (conditional_after=) for landmark-based predictions. With ci=True, confidence intervals are included.

  4. Mean (type="mean"): the expected survival time E[T] (unconditional) or the conditional mean E[T \mid T > t_0] when conditional_after= is provided. Computed via closed-form formulas for all distributions. Returns an array of shape (n_subjects,).

  5. Mean remaining (type="mean_remaining"): expected remaining lifetime E[T - t_0 \mid T > t_0] for subjects known to have survived past t_0. Requires conditional_after=. Returns an array of shape (n_subjects,).

  6. RMST (type="rmst"): restricted mean survival time E[\min(T, \tau)] up to the restriction time tau. Requires the tau argument. Returns an array of shape (n_subjects,).

Parameters

newdata: Any = None

Covariate values for prediction. A DataFrame (Pandas or Polars), 2-D array, or None (the default). If None, uses the training data (design matrix used at fit time). Must have the same columns/features as the training data.

type: str = "survival"

Prediction type (default "survival"):

  • "lp": Linear predictor X\beta (log-time location). Returns an array.
  • "quantile": Survival-time quantiles at failure probabilities p. Returns a frame with p column and one column per subject.
  • "survival": Survival probabilities S(t \mid x) at times in times. Returns a frame with time column and one column per subject (one per query time, one per subject in newdata).
times: Any = None

Query times for type="survival" (ignored for other types). An array-like of floats. If None (the default), uses an automatic grid based on the fitted distribution (50 equally spaced times on the log scale, rounded).

p: Any = 0.5

Failure probabilities for type="quantile" (ignored for other types). Can be a scalar (e.g., 0.5 for median) or array-like. Default is 0.5 (median). Must be in (0, 1).

tau: Any = None

Restriction time for type="rmst". Scalar float giving the upper limit of integration. Required when type="rmst", ignored otherwise.

conditional_after: Any = None

For type="survival", optionally compute conditional survival P(T > t \mid T > c) = S(t) / S(c). Also used with type="mean" and type="mean_remaining" to condition on surviving past a landmark time t_0. Scalar (same conditioning time for all subjects) or array-like (one per subject). The default is None (unconditional).

ci: bool = False

If True (survival only), include confidence intervals (_lower and _upper columns per subject). Default is False. Not supported with conditional_after.

conf_type: str = "log-log"

Confidence interval transform (used only if ci=True and type="survival"):

  • "log-log" (default): Log-log transform. Bounds respect the constraint that survival S(t) \in (0, 1). Recommended.
  • "plain": Wald bounds without transform. Simple but may produce invalid bounds (survival < 0 or > 1).
format: str | None = None
Output format for the returned frame (type="quantile" or "survival"): None (the default), "pandas", "polars", or "pyarrow". When None, a backend is auto-detected (Polars, then Pandas, then PyArrow). Ignored for type="lp", "mean", "mean_remaining", and "rmst" (which always return arrays).

Returns

ndarray or DataFrame
If type="lp": an array of shape (n_subjects,) containing log-time locations. If type="quantile": a DataFrame with columns p (failure probabilities) and subject_1, subject_2, etc. containing survival times at each p. If type="survival": a DataFrame with columns time (query times) and subject_1, subject_2, etc. containing survival probabilities at each time, optionally with _lower and _upper columns for confidence intervals. If type="mean": an array of shape (n_subjects,) with E[T] or E[T \mid T > t_0]. If type="mean_remaining": an array of shape (n_subjects,) with E[T - t_0 \mid T > t_0]. If type="rmst": an array of shape (n_subjects,) with E[\min(T, \tau)].

Details

The AFT model assumes \log(T) = X\beta + \sigma\varepsilon, where \varepsilon follows a parametric error distribution (Weibull, lognormal, etc.). Predictions are made by evaluating the CDF/survival function of this distribution at covariate-adjusted locations. All predictions respect the fitted distribution and scale parameter. If the model was fit with threshold=True, every time-scale prediction (quantiles, survival times, means) is shifted by threshold_, and query times at or below threshold_ report S(t) = 1 exactly (the event cannot yet have occurred).

Predictions assume the model is well-specified. For flexible models, consider parametric bootstrap to quantify uncertainty.

Examples

Fit a Weibull AFT model on the bundled lung dataset, then predict the linear predictor (log-time location) for the first two subjects:

import greenwood as gw

# Load data and fit a Weibull AFT model
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

# Predict the linear predictor for the first two subjects
aft.predict(lung[["age", "sex"]][:2], type="lp")
array([5.74991419, 5.82345873])

Predicted survival-time quantiles for the first two subjects at the lower quartile, median, and upper quartile (a table, so pass format=):

# Predict survival-time quartiles for the first two subjects
aft.predict(lung[["age", "sex"]][:2], type="quantile", p=[0.25, 0.5, 0.75],
            format="polars")
shape: (3, 3)
psubject_1subject_2
f64f64f64
0.25122.785921132.156509
0.5238.303411256.489886
0.75401.903952432.575842

Read survival probabilities off the fitted curves at chosen times. Here are the estimates at 180 and 365 days for those same two subjects:

# Predict survival probabilities at 180 and 365 days
aft.predict(lung[["age", "sex"]][:2], type="survival", times=[180, 365],
            format="polars")
shape: (2, 3)
timesubject_1subject_2
f64f64f64
180.00.6201630.648318
365.00.2952110.330653

Predict conditional survival given already having survived to 100 days:

# Predict conditional survival given survival to 100 days
aft.predict(lung[["age", "sex"]][:2], type="survival", times=[180, 365],
            conditional_after=100, format="polars")
shape: (2, 3)
timesubject_1subject_2
f64f64f64
180.00.7720930.790875
365.00.3675330.40336

Add confidence intervals with ci=True:

# Include confidence intervals for the survival predictions
aft.predict(lung[["age", "sex"]][:2], type="survival", times=[180, 365],
            ci=True, format="polars")
shape: (2, 7)
timesubject_1subject_1_lowersubject_1_uppersubject_2subject_2_lowersubject_2_upper
f64f64f64f64f64f64f64
180.00.6201630.5359480.6935180.6483180.5877870.70227
365.00.2952110.2033650.3927510.3306530.2574350.405532

Unconditional mean survival time per subject:

# Predict unconditional mean survival time
aft.predict(lung[["age", "sex"]][:2], type="mean")
array([289.02751331, 311.0850723 ])

Expected remaining lifetime given the subject has already survived 100 days:

# Predict expected remaining lifetime given survival past 100 days
aft.predict(lung[["age", "sex"]][:2], type="mean_remaining",
            conditional_after=100)
array([246.28741535, 267.29482905])

Restricted mean survival time up to 365 days:

# Predict restricted mean survival time up to 365 days
aft.predict(lung[["age", "sex"]][:2], type="rmst", tau=365)
array([230.17704711, 239.03381784])

predict_expectation()

Predict the expected (restricted mean) survival time for each subject.

Usage

Source

predict_expectation(
    newdata=None,
    *,
    tau,
    ci=False,
    format=None,
)

The restricted mean survival time (RMST) up to horizon \tau is \mathrm{RMST}_i(\tau) = \int_0^{\tau} S(t \mid x_i)\, dt. For the AFT model with Weibull or log-normal errors, this is computed in closed form using the mean minus tail partial moment. For log-logistic with \sigma \ge 1, numerical integration is used.

When ci=True, confidence intervals are computed via the delta method on the linear predictor.

Parameters

newdata: Any = None

Covariate values for prediction. A DataFrame (Pandas or Polars), 2-D array, or None (the default). If None, uses the training data.

tau: float

The restriction time (time horizon). Must be positive.

ci: bool = False

If True, include confidence intervals. Default is False.

format: str | None = None
Output format: None (auto-detect), "pandas", "polars", or "pyarrow".

Returns

DataFrame
A DataFrame with a tau column and columns subject_1, subject_2, etc. containing the RMST for each subject. With ci=True, additional subject_N_lower and subject_N_upper columns are included.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

# Expected survival time up to one year for three subjects
aft.predict_expectation(lung[["age", "sex"]][:3], tau=365, format="polars")
shape: (1, 4)
tausubject_1subject_2subject_3
f64f64f64f64
365.0230.177047239.033818255.765765

With confidence intervals:

aft.predict_expectation(lung[["age", "sex"]][:3], tau=365, ci=True, format="polars")
shape: (1, 10)
tausubject_1subject_1_lowersubject_1_uppersubject_2subject_2_lowersubject_2_uppersubject_3subject_3_lowersubject_3_upper
f64f64f64f64f64f64f64f64f64f64
365.0230.177047204.676785253.614192239.033818220.200431256.489586255.765765235.827951273.650808

predict_median()

Predict the median survival time for each subject.

Usage

Source

predict_median(
    newdata=None,
    *,
    ci=False,
    format=None,
)

Convenience wrapper around predict_quantile(p=0.5). See predict_quantile for full documentation.

Parameters

newdata: Any = None

Covariate values for prediction. A DataFrame (Pandas or Polars), 2-D array, or None (the default). If None, uses the training data.

ci: bool = False

If True, include confidence intervals. Default is False.

format: str | None = None
Output format: None (auto-detect), "pandas", "polars", or "pyarrow".

Returns

DataFrame
A single-row DataFrame with columns p, subject_1, subject_2, etc. containing the median survival time for each subject. With ci=True, additional subject_N_lower and subject_N_upper columns are included.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

aft.predict_median(lung[["age", "sex"]][:3], format="polars")
shape: (1, 4)
psubject_1subject_2subject_3
f64f64f64f64
0.5238.303411256.489886297.132539

With confidence intervals:

aft.predict_median(lung[["age", "sex"]][:3], ci=True, format="polars")
shape: (1, 10)
psubject_1subject_1_lowersubject_1_uppersubject_2subject_2_lowersubject_2_uppersubject_3subject_3_lowersubject_3_upper
f64f64f64f64f64f64f64f64f64f64
0.5238.303411194.911017291.356111256.489886219.937013299.117737297.132539249.679406353.604439

predict_quantile()

Predict survival-time quantiles for each subject.

Usage

Source

predict_quantile(
    newdata=None,
    *,
    p=0.5,
    ci=False,
    format=None,
)

The quantile at failure probability p is \hat{t}_p = \exp(\hat{\mu} + \hat{\sigma} w_p), where w_p is the p-th quantile of the standardized error distribution and \hat{\mu} = x^\top \hat{\beta} is the fitted linear predictor. This is a closed-form computation.

When ci=True, confidence intervals are computed on the log scale (where the variance depends only on coefficient uncertainty) and exponentiated: \exp(\hat{\mu} + \hat{\sigma} w_p \pm z_{\alpha/2} \cdot \text{SE}(\hat{\mu})).

Parameters

newdata: Any = None

Covariate values for prediction. A DataFrame (Pandas or Polars), 2-D array, or None (the default). If None, uses the training data.

p: Any = 0.5

Failure probability or probabilities at which to compute quantiles. Can be a scalar (e.g., 0.5 for median) or array-like (e.g., [0.25, 0.5, 0.75] for quartiles). Must be in (0, 1). Default is 0.5.

ci: bool = False

If True, include confidence intervals. Default is False.

format: str | None = None
Output format: None (auto-detect), "pandas", "polars", or "pyarrow".

Returns

DataFrame
A DataFrame with a p column listing the failure probabilities, and columns subject_1, subject_2, etc. containing the corresponding quantile for each subject. With ci=True, additional subject_N_lower and subject_N_upper columns are included.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

# Predicted survival-time quartiles for three subjects
aft.predict_quantile(lung[["age", "sex"]][:3], p=[0.25, 0.5, 0.75], format="polars")
shape: (3, 4)
psubject_1subject_2subject_3
f64f64f64f64
0.25122.785921132.156509153.097651
0.5238.303411256.489886297.132539
0.75401.903952432.575842501.120573

With confidence intervals at the median:

aft.predict_quantile(lung[["age", "sex"]][:3], p=0.5, ci=True, format="polars")
shape: (1, 10)
psubject_1subject_1_lowersubject_1_uppersubject_2subject_2_lowersubject_2_uppersubject_3subject_3_lowersubject_3_upper
f64f64f64f64f64f64f64f64f64f64
0.5238.303411194.911017291.356111256.489886219.937013299.117737297.132539249.679406353.604439

residuals()

Return diagnostic residuals from the fitted AFT model.

Usage

Source

residuals(
    type="martingale",
    *,
    format=None,
)

Parameters

type: str = "martingale"

Type of residuals to return:

  • "response": Raw residuals on the log-time scale, \log(t) - X\hat\beta. One per observation.
  • "cox_snell": -\log \hat S(t_i \mid x_i), the estimated cumulative hazard at the observed time. Under a correct model, these follow \text{Exp}(1) for uncensored observations.
  • "martingale" (default): \delta_i - r^{CS}_i where \delta is the event indicator and r^{CS} is the Cox-Snell residual. Range (-\infty, 1].
  • "deviance": Signed likelihood-ratio residuals. Positive for censored observations; signed by z for events. More symmetrically distributed than martingale residuals.
  • "score": Efficient score residuals (derivative of each observation’s log-likelihood contribution w.r.t. the coefficients). One row per observation, one column per term.
  • "dfbeta": Approximate change in each coefficient if observation i were deleted. One row per observation, one column per term.
  • "dfbetas": Standardized dfbeta (dfbeta divided by the coefficient SE). Comparable across covariates on different scales.
format: str | None = None
Output format for multi-column residual types: None (auto-detect), "pandas", "polars", or "pyarrow". Returns a numpy array for "response", "cox_snell", "martingale", and "deviance".

Returns

ndarray or DataFrame
For "response", "cox_snell", "martingale", and "deviance": a 1-D array (one value per observation). For all other types: a DataFrame with one column per term.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

aft.residuals("martingale")[:5]
array([ 0.03431429, -0.48239431, -3.51167189,  0.55537868, -2.13585758])
aft.residuals("dfbeta", format="polars")
shape: (228, 3)
(Intercept)agesex
f64f64f64
0.001013-0.0000230.000222
-0.0022990.00014-0.003267
0.157048-0.001688-0.025824
-0.0225470.0002310.004057
0.060287-0.000478-0.015293
-0.0222560.000461-0.003367
0.0336-0.00046-0.002393
-0.009340.0001130.002164
0.0013970.000065-0.002755
0.001054-0.0000660.003102

test_distributions()

Compare the generalized gamma fit against nested sub-models.

Usage

Source

test_distributions(
    *,
    format=None,
)

Fits Weibull (Q=1) and log-normal (Q=0) sub-models with the same covariates and tests each against the generalized gamma using a likelihood ratio test with 1 degree of freedom. This helps determine whether the extra flexibility of the generalized gamma is warranted or whether a simpler distribution is adequate.

Only available when dist="gengamma".

Parameters

format: str | None = None
Output format: None, "pandas", "polars", or "pyarrow".

Returns

pandas.DataFrame, polars.DataFrame, or pyarrow.Table
One row per sub-model with columns for the distribution name, log-likelihood, AIC, likelihood ratio statistic, degrees of freedom, and p-value.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
gg = gw.AFT("gengamma").fit(y, lung[["age", "sex"]])
gg.test_distributions(format="polars")
shape: (4, 6)
distloglikaiclr_statisticdfp_value
strf64f64f64i64f64
"weibull"-1147.0544312302.1088630.011.0
"lognormal"-1158.7501432325.50028523.39142210.000001
"exponential"-1156.0990372318.19807418.08921110.000021
"loglogistic"-1152.8972252313.79445111.68558810.00063

to_frame()

Return the coefficient table as a DataFrame.

Usage

Source

to_frame(
    *,
    format=None,
)

Exports one row per term, including the intercept, with coefficient estimates, standard errors, Wald statistics, p-values, and confidence limits.

Parameters

format: str | None = None
Output format: None (default), "pandas", "polars", or "pyarrow". When None, a backend is auto-detected (Polars, then Pandas, then PyArrow).

Returns

pandas.DataFrame, polars.DataFrame, or pyarrow.Table
A tidy table with columns term, estimate, std_error, statistic, p_value, conf_low, and conf_high.

Raises

ImportError
If the requested (or, when auto-detecting, any) DataFrame library is not installed.

Examples

Fit a Weibull AFT model on the bundled lung dataset, then export its coefficient table as a Polars frame:

import greenwood as gw

# Load data and fit a Weibull AFT model
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
aft = gw.AFT("weibull").fit(y, lung[["age", "sex"]])

# Export the coefficient table as a Polars DataFrame
aft.to_frame(format="polars")
shape: (3, 7)
termestimatestd_errorstatisticp_valueconf_lowconf_high
strf64f64f64f64f64f64
"(Intercept)"6.2748790.48135513.0358597.6500e-395.331447.218318
"age"-0.0122570.006957-1.7617940.078104-0.0258940.001379
"sex"0.3820850.1274732.9973740.0027230.1322420.631927

Request a different backend with format=:

# Export as a Pandas DataFrame instead
aft.to_frame(format="pandas")
term estimate std_error statistic p_value conf_low conf_high
0 (Intercept) 6.274879 0.481355 13.035859 7.650039e-39 5.331440 7.218318
1 age -0.012257 0.006957 -1.761794 7.810410e-02 -0.025894 0.001379
2 sex 0.382085 0.127473 2.997374 2.723163e-03 0.132242 0.631927