type is one of "lp" (centered linear predictor), "risk" (exp(lp)), or "survival". For "survival", returns a frame of survival probabilities at times (defaulting to the union of all event times), one column per row of newdata.
For stratified models, each subject must be assigned to a stratum. When newdata is provided, pass strata= with one label per row matching a stratum seen at fit time. When newdata is None, stratum assignments are taken from the fitted data.
conditional_after (a scalar or one value per subject) predicts survival conditional on having already survived to that time: the returned value at time t is P(T > t \mid T > c) = S(t) / S(c), and is 1 for t \le c.
With ci=True (survival only), the frame also carries _lower and _upper columns per subject: a pointwise confidence band from the cumulative-hazard standard error (the log transform used by R’s survfit), at the model’s conf_level.
trajectory predicts survival for a single subject whose covariates change over time. It is a DataFrame (any backend) with columns tstart, tstop, and one column per covariate in the fitted model. Each row defines a constant-covariate interval; the covariate values in interval k apply to (t_k^{\text{start}}, t_k^{\text{stop}}]. The survival at time t is accumulated as
S(t) = \exp\!\Bigl(-\sum_k r_k \cdot \bigl[H_0(\min(t,\, t_k^{\text{stop}})) -
H_0(t_k^{\text{start}})\bigr]\Bigr)
where r_k = \exp(\hat{\beta}^\top x_k) and the sum runs over all intervals where t_k^{\text{start}} < t. For times beyond the last interval the last covariate value is carried forward (the baseline hazard keeps accumulating). Mutually exclusive with newdata; requires type="survival".
Examples
The default type="lp" returns the centered linear predictor as a NumPy array, one value per fitted subject:
import greenwood as gw
# Load data and fit a Cox model
lung = gw.load_dataset("lung", backend="polars")
y = gw.Surv.right(lung["time"], event=(lung["status"] == 2))
cox = gw.CoxPH().fit(y, lung[["age", "sex"]])
# Predict the centered linear predictor for the first five subjects
cox.predict(type="lp")[:5]
array([0.3995047 , 0.2972327 , 0.09268872, 0.10973405, 0.16087005])
With type="survival" and newdata, the result is a frame of survival probabilities at the requested times, one column per new subject. Pass format= to choose the backend (here, Polars):
# Predict survival probabilities for three subjects at 180 and 365 days
cox.predict(
lung[["age", "sex"]][:3], type="survival", times=[180, 365], format="polars"
)
shape: (2, 4)| time | subject_1 | subject_2 | subject_3 |
|---|
| f64 | f64 | f64 | f64 |
| 180.0 | 0.62234 | 0.651705 | 0.705421 |
| 365.0 | 0.268757 | 0.305376 | 0.380304 |
Passing ci=True adds pointwise confidence bands, and conditional_after= gives survival conditional on having already survived to a landmark time.
With trajectory, survival is computed along a covariate path for a single subject:
import pandas as pd
pbcseq = gw.load_dataset("pbcseq", backend="pandas")
base = (pbcseq.drop_duplicates("id")[["id", "futime", "status"]]
.rename(columns={"futime": "time"}))
long = gw.split_episodes(
base, pbcseq[["id", "day", "bili", "albumin", "protime"]],
id="id", time="time", event="status", visit_time="day", format="pandas",
)
long = long.dropna(subset=["bili", "albumin", "protime"])
long["event_bin"] = (long["status"] == 2).astype(int)
y = gw.Surv.counting(long["tstart"], long["tstop"], long["event_bin"])
cox = gw.CoxPH().fit(y, long[["bili", "albumin", "protime"]])
# Subject 1's covariate path (two visits)
tvc_path = pd.DataFrame({
"tstart": [0.0, 192.0],
"tstop": [192.0, 400.0],
"bili": [14.5, 21.3],
"albumin": [2.60, 2.94],
"protime": [12.2, 11.2],
})
cox.predict(trajectory=tvc_path, times=[100, 200, 300, 400], format="pandas")
/var/folders/s8/bj_jsx3d7jqd2btw7bwm6yx80000gp/T/ipykernel_11078/1120825321.py:14: UserWarning: Subjects in counting-process data have different start times, some much larger than 0. This may indicate that start/stop times are calendar time rather than subject-relative time. Each subject's timeline should begin at 0. If you have calendar dates, subtract each subject's entry date from their start/stop times before fitting.
cox = gw.CoxPH().fit(y, long[["bili", "albumin", "protime"]])
|
time |
subject_1 |
| 0 |
100.0 |
0.851568 |
| 1 |
200.0 |
0.654596 |
| 2 |
300.0 |
0.562411 |
| 3 |
400.0 |
0.395678 |