Fetching contributors…
Cannot retrieve contributors at this time
217 lines (129 sloc) 6 KB



Install via pip:

pip install lifelines

Kaplan-Meier and Nelson-Aalen


For readers looking for an introduction to survival analysis, it's recommended to start at :ref:`Introduction to Survival Analysis`

Let's start by importing some data. We need the durations that individuals are observed for, and whether they "died" or not.

from lifelines.datasets import load_waltons
df = load_waltons() # returns a Pandas DataFrame

    T  E    group
0   6  1  miR-137
1  13  1  miR-137
2  13  1  miR-137
3  13  1  miR-137
4  19  1  miR-137

T = df['T']
E = df['E']

T is an array of durations, E is a either boolean or binary array representing whether the "death" was observed (alternatively an individual can be censored).


lifelines assumes all "deaths" are observed unless otherwise specified.

from lifelines import KaplanMeierFitter
kmf = KaplanMeierFitter(), event_observed=E)  # or, more succinctly,, E)

After calling the fit method, we have access to new properties like survival_function_ and methods like plot(). The latter is a wrapper around Panda's internal plotting library.



Multiple groups

groups = df['group']
ix = (groups == 'miR-137')[~ix], E[~ix], label='control')
ax = kmf.plot()[ix], E[ix], label='miR-137')
ax = kmf.plot(ax=ax)


Similar functionality exists for the NelsonAalenFitter:

from lifelines import NelsonAalenFitter
naf = NelsonAalenFitter(), event_observed=E)

but instead of a survival_function_ being exposed, a cumulative_hazard_ is.


Similar to Scikit-Learn, all statistically estimated quantities append an underscore to the property name.

Getting Data in The Right Format

Often you'll have data that looks like:

start_time, end_time

Lifelines has some utility functions to transform this dataset into duration and censorship vectors:

from lifelines.utils import datetimes_to_durations

# start_times is a vector of datetime objects
# end_times is a vector of (possibly missing) datetime objects.
T, E = datetimes_to_durations(start_times, end_times, freq='h')

Alternatively, perhaps you are interested in viewing the survival table given some durations and censorship vectors.

from lifelines.utils import survival_table_from_events

table = survival_table_from_events(T, E)

          removed  observed  censored  entrance  at_risk
0               0         0         0       163      163
6               1         1         0         0      163
7               2         1         1         0      162
9               3         3         0         0      160
13              3         3         0         0      157

Survival Regression

While the above KaplanMeierFitter and NelsonAalenFitter are useful, they only give us an "average" view of the population. Often we have specific data at the individual level, either continuous or categorical, that we would like to use. For this, we turn to survival regression, specifically AalenAdditiveFitter and CoxPHFitter.

from lifelines.datasets import load_regression_dataset
regression_dataset = load_regression_dataset()


The input of the fit method's API in a regression is different. All the data, including durations, censorships and covariates must be contained in a Pandas DataFrame (yes, it must be a DataFrame). The duration column and event occurred column must be specified in the call to fit.

from lifelines import CoxPHFitter

# Using Cox Proportional Hazards model
cph = CoxPHFitter(), 'T', event_col='E')

      duration col = T
         event col = E
number of subjects = 200
  number of events = 189
    log-likelihood = -807.620
  time fit was run = 2018-10-23 02:44:18 UTC

       coef  exp(coef)  se(coef)      z      p  lower 0.95  upper 0.95
var1 0.2222     1.2488    0.0743 2.9920 0.0028      0.0767      0.3678  **
var2 0.0510     1.0523    0.0829 0.6148 0.5387     -0.1115      0.2134
var3 0.2183     1.2440    0.0758 2.8805 0.0040      0.0698      0.3669  **
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Concordance = 0.580
Likelihood ratio test = 15.540 on 3 df, p=0.00141



If we focus on Aalen's Additive model,

# Using Aalen's Additive model
from lifelines import AalenAdditiveFitter
aaf = AalenAdditiveFitter(fit_intercept=False), 'T', event_col='E')

Like CoxPHFitter, after fitting you'll have access to properties like cumulative_hazards_ and methods like plot, predict_cumulative_hazards, and predict_survival_function. The latter two methods require an additional argument of individual covariates:

X = regression_dataset.drop(['E', 'T'], axis=1)
aaf.predict_survival_function(X.iloc[10:12]).plot()  # get the unique survival functions of two subjects


Like the above estimators, there is also a built-in plotting method: