lifelines 0.29.0__py3-none-any.whl → 0.30.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
  from functools import partial, wraps
4
4
  from inspect import getfullargspec
5
- from datetime import datetime
5
+ from datetime import datetime, UTC
6
6
  from textwrap import dedent
7
7
  import typing as t
8
8
  import collections
@@ -1229,11 +1229,15 @@ class ParametricUnivariateFitter(UnivariateFitter):
1229
1229
  # use numerical solver to find the value p = e^{-H(t)}. I think I could use `root` in scipy
1230
1230
  # instead of the scalar version. TODO
1231
1231
  def _find_root(_p):
1232
- f = lambda t: _p - self.survival_function_at_times(t).values
1233
- fprime = lambda t: self.survival_function_at_times(t).values * self.hazard_at_times(t).values
1232
+ survival_at_t = lambda t: float(self.survival_function_at_times(t).values[0])
1233
+ hazard_at_t = lambda t: float(self.hazard_at_times(t).values[0])
1234
+ f = lambda t: _p - survival_at_t(t)
1235
+ fprime = lambda t: survival_at_t(t) * hazard_at_t(t)
1234
1236
  return root_scalar(f, bracket=(1e-10, 2 * self.timeline[-1]), fprime=fprime, x0=1.0).root
1235
1237
 
1236
1238
  try:
1239
+ if np.isscalar(p):
1240
+ return float(_find_root(p))
1237
1241
  find_root = np.vectorize(_find_root, otypes=[float])
1238
1242
  return find_root(p)
1239
1243
  except ValueError:
@@ -1776,7 +1780,7 @@ class ParametricRegressionFitter(RegressionFitter):
1776
1780
  fit_options: Optional[dict] = None,
1777
1781
  ) -> ParametricRegressionFitter:
1778
1782
 
1779
- self._time_fit_was_called = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
1783
+ self._time_fit_was_called = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") + " UTC"
1780
1784
  self._n_examples = df.shape[0]
1781
1785
  self.weights_col = weights_col
1782
1786
  self.entry_col = entry_col
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import warnings
3
- from datetime import datetime
3
+ from datetime import datetime, UTC
4
4
  import time
5
5
 
6
6
  import numpy as np
@@ -153,7 +153,7 @@ class AalenAdditiveFitter(RegressionFitter):
153
153
  aaf.print_summary()
154
154
 
155
155
  """
156
- self._time_fit_was_called = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
156
+ self._time_fit_was_called = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") + " UTC"
157
157
 
158
158
  df = df.copy()
159
159
 
@@ -244,7 +244,7 @@ class AalenAdditiveFitter(RegressionFitter):
244
244
 
245
245
  hazards_[i, :] = v
246
246
 
247
- variance_hazards_[i, :] = (V ** 2).sum(1)
247
+ variance_hazards_[i, :] = (V**2).sum(1)
248
248
 
249
249
  X[exits, :] = 0
250
250
 
@@ -500,7 +500,7 @@ It's important to know that the naive variance estimates of the coefficients are
500
500
  # normally (weights * X).dot(Y) / X.dot(weights * X), but we have a slightly different form here.
501
501
  beta = X.dot(Y) / X.dot(weights * X)
502
502
  errors = Y.values - np.outer(X, beta)
503
- var = (errors ** 2).sum(0) / (Y.shape[0] - 2) / X.dot(weights * X)
503
+ var = (errors**2).sum(0) / (Y.shape[0] - 2) / X.dot(weights * X)
504
504
  return beta, np.sqrt(var)
505
505
 
506
506
  weights = survival_table_from_events(self.durations, self.event_observed).loc[self._index, "at_risk"].values
@@ -5,7 +5,7 @@ import pandas as pd
5
5
  import warnings
6
6
 
7
7
  from lifelines.fitters import NonParametricUnivariateFitter
8
- from lifelines.utils import _preprocess_inputs, inv_normal_cdf, CensoringType, coalesce
8
+ from lifelines.utils import _preprocess_inputs, inv_normal_cdf, CensoringType, coalesce, LinearAccumulator, QuadraticAccumulator
9
9
  from lifelines import KaplanMeierFitter
10
10
  from lifelines.plotting import _plot_estimate
11
11
 
@@ -219,22 +219,28 @@ class AalenJohansenFitter(NonParametricUnivariateFitter):
219
219
  ci_labels = ["%s_upper_%g" % (self._label, ci), "%s_lower_%g" % (self._label, ci)]
220
220
  assert len(ci_labels) == 2, "ci_labels should be a length 2 array."
221
221
 
222
- # Have to loop through each time independently. Don't think there is a faster way
222
+ # Use prefix sum algorithm to reduce time complexity to O(n), by cumulatively updating terms.
223
+ first_term_function = QuadraticAccumulator()
224
+ second_term = 0
225
+ third_term_function = LinearAccumulator()
223
226
  all_vars = []
224
227
  for _, r in df.iterrows():
225
- sf = df.loc[df.index <= r.name].copy()
226
228
  F_t = float(r["Ft"])
227
- first_term = np.sum((F_t - sf["Ft"]) ** 2 * sf["observed"] / sf["at_risk"] / (sf["at_risk"] - sf["observed"]))
228
- second_term = np.sum(
229
- sf["lagS"] ** 2
230
- / sf["at_risk"]
231
- * sf[self.label_cmprisk]
232
- / sf["at_risk"]
233
- * (sf["at_risk"] - sf[self.label_cmprisk])
234
- / sf["at_risk"]
229
+
230
+ first_term_coefficient = r["observed"] / r["at_risk"] / (r["at_risk"] - r["observed"])
231
+ first_term_function.add_quadratic_term(a = first_term_coefficient, b = F_t)
232
+
233
+ second_term += (
234
+ (r["lagS"] ** 2)
235
+ * r[self.label_cmprisk]
236
+ * (r["at_risk"] - r[self.label_cmprisk])
237
+ / (r["at_risk"] ** 3)
235
238
  )
236
- third_term = np.sum((F_t - sf["Ft"]) / sf["at_risk"] * sf["lagS"] * sf[self.label_cmprisk] / sf["at_risk"])
237
- variance = first_term + second_term - 2 * third_term
239
+
240
+ third_term_coefficient = r["lagS"] * r[self.label_cmprisk] / (r["at_risk"] ** 2)
241
+ third_term_function.add_linear_term(a = third_term_coefficient, b = F_t)
242
+
243
+ variance = first_term_function.evaluate(F_t) + second_term - 2 * third_term_function.evaluate(F_t)
238
244
  all_vars.append(variance)
239
245
  df["variance"] = all_vars
240
246
 
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
 
4
- from datetime import datetime
4
+ from datetime import datetime, UTC
5
5
  import warnings
6
6
  import time
7
7
  from typing import Optional
@@ -172,7 +172,7 @@ class CoxTimeVaryingFitter(SemiParametricRegressionFitter, ProportionalHazardMix
172
172
  self.stop_col = stop_col
173
173
  self.start_col = start_col
174
174
  self.formula = formula
175
- self._time_fit_was_called = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
175
+ self._time_fit_was_called = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") + " UTC"
176
176
 
177
177
  df = df.copy()
178
178
 
@@ -801,7 +801,9 @@ See https://stats.stackexchange.com/questions/11109/how-to-deal-with-perfect-sep
801
801
  hazards = self.predict_partial_hazard(tv_data).values
802
802
 
803
803
  unique_death_times = np.unique(stop[events.values])
804
- baseline_hazard_ = pd.DataFrame(np.zeros_like(unique_death_times).astype(float), index=unique_death_times, columns=["baseline hazard"])
804
+ baseline_hazard_ = pd.DataFrame(
805
+ np.zeros_like(unique_death_times).astype(float), index=unique_death_times, columns=["baseline hazard"]
806
+ )
805
807
 
806
808
  for t in unique_death_times:
807
809
  ix = (start.values < t) & (t <= stop.values)
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
  from typing import Callable, Iterator, List, Optional, Tuple, Union, Any, Iterable
4
4
  from textwrap import dedent, fill
5
- from datetime import datetime
5
+ from datetime import datetime, UTC
6
6
  import warnings
7
7
  import time
8
8
 
@@ -1214,7 +1214,7 @@ class SemiParametricPHFitter(ProportionalHazardMixin, SemiParametricRegressionFi
1214
1214
  cph.predict_median(df)
1215
1215
 
1216
1216
  """
1217
- self._time_fit_was_called = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
1217
+ self._time_fit_was_called = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S") + " UTC"
1218
1218
  self.duration_col = duration_col
1219
1219
  self.event_col = event_col
1220
1220
  self.robust = robust
@@ -2693,9 +2693,13 @@ See https://stats.stackexchange.com/q/11109/11867 for more.\n",
2693
2693
  if self.strata:
2694
2694
  df = df.set_index(self.strata)
2695
2695
 
2696
- df = df.sort_values([self.duration_col, self.event_col])
2696
+ df = df.sort_values([col for col in [self.duration_col, self.event_col] if (col is not None)])
2697
2697
  T = df.pop(self.duration_col).astype(float)
2698
- E = df.pop(self.event_col).astype(bool)
2698
+ E = (
2699
+ df.pop(self.event_col)
2700
+ if (self.event_col is not None)
2701
+ else pd.Series(np.ones(len(df.index)), index=df.index, name="E")
2702
+ ).astype(bool)
2699
2703
  W = df.pop(self.weights_col) if self.weights_col else pd.Series(np.ones_like(E), index=T.index)
2700
2704
  entries = df.pop(self.entry_col) if self.entry_col else None
2701
2705
 
@@ -2991,7 +2995,11 @@ class ParametricSplinePHFitter(ParametricCoxModelFitter, SplineFitterMixin):
2991
2995
 
2992
2996
  @staticmethod
2993
2997
  def _strata_labeler(stratum, i):
2994
- return "s%s_phi%d_" % (stratum, i)
2998
+ try:
2999
+ return "s%s_phi%d_" % (tuple(str(s) for s in stratum), i)
3000
+ except:
3001
+ # singleton
3002
+ return "s%s_phi%d_" % (stratum, i)
2995
3003
 
2996
3004
  @property
2997
3005
  def _fitted_parameter_names(self):
@@ -3112,7 +3120,11 @@ class ParametricPiecewiseBaselinePHFitter(ParametricCoxModelFitter, Proportional
3112
3120
 
3113
3121
  @staticmethod
3114
3122
  def _strata_labeler(stratum, i):
3115
- return "s%s_lambda%d_" % (stratum, i)
3123
+ try:
3124
+ return "s%s_lambda%d_" % (tuple(str(s) for s in stratum), i)
3125
+ except:
3126
+ # singleton
3127
+ return "s%s_lambda%d_" % (stratum, i)
3116
3128
 
3117
3129
  @property
3118
3130
  def _fitted_parameter_names(self):
lifelines/plotting.py CHANGED
@@ -540,7 +540,10 @@ def add_at_risk_counts(
540
540
  event_table_slice.loc[:tick, ["at_risk", "censored", "observed"]]
541
541
  .agg(
542
542
  {
543
- "at_risk": lambda x: x.tail(1).values,
543
+ # `Series.tail(1).values` is a 1D array of length 1. In NumPy>=2.4,
544
+ # `int(np.array([1]))` raises `TypeError: only 0-dimensional arrays can be converted to Python scalars`.
545
+ # Extract a Python scalar for compatibility.
546
+ "at_risk": lambda x: x.tail(1).values.item(),
544
547
  "censored": "sum",
545
548
  "observed": "sum",
546
549
  }
@@ -554,7 +557,7 @@ def add_at_risk_counts(
554
557
  )
555
558
  .fillna(0)
556
559
  )
557
- counts.extend([int(c) for c in event_table_slice.loc[rows_to_show]])
560
+ counts.extend([int(np.asarray(c).item()) for c in event_table_slice.loc[rows_to_show]])
558
561
  else:
559
562
  counts.extend([0 for _ in range(n_rows)])
560
563
  if n_rows > 1:
lifelines/statistics.py CHANGED
@@ -111,14 +111,14 @@ class StatisticalResult:
111
111
 
112
112
  """
113
113
  if style is not None:
114
- self._print_specific_style(style)
114
+ self._print_specific_style(style, decimals=decimals, **kwargs)
115
115
  else:
116
116
  try:
117
- from IPython.display import display
117
+ from IPython.display import HTML, display
118
118
 
119
- display(self)
119
+ display(HTML(self.to_html(decimals=decimals, **kwargs)))
120
120
  except ImportError:
121
- self._ascii_print()
121
+ self._ascii_print(decimals=decimals, **kwargs)
122
122
 
123
123
  def _html_print(self, decimals=2, **kwargs):
124
124
  print(self.to_html(decimals, **kwargs))
@@ -175,7 +175,6 @@ class StatisticalResult:
175
175
  def to_ascii(self, decimals=2, **kwargs):
176
176
  extra_kwargs = dict(list(self._kwargs.items()) + list(kwargs.items()))
177
177
  meta_data = self._stringify_meta_data(extra_kwargs)
178
-
179
178
  df = self.summary
180
179
 
181
180
  s = "<lifelines.StatisticalResult: {0}>".format(self.test_name)
@@ -835,7 +834,7 @@ def multivariate_logrank_test(
835
834
  assert abs(Z_j.sum()) < 10e-8, "Sum is not zero." # this should move to a test eventually.
836
835
 
837
836
  # compute covariance matrix
838
- factor = (((n_i - d_i) / (n_i - 1)).replace([np.inf, np.nan], 1)) * d_i / n_i ** 2
837
+ factor = (((n_i - d_i) / (n_i - 1)).replace([np.inf, np.nan], 1)) * d_i / n_i**2
839
838
  n_ij["_"] = n_i.values
840
839
  V_ = (n_ij.mul(w_i, axis=0)).mul(np.sqrt(factor), axis="index").fillna(0) # weighted V_
841
840
  V = -np.dot(V_.T, V_)
@@ -923,7 +922,7 @@ def proportional_hazard_test(
923
922
  def compute_statistic(times, resids, n_deaths):
924
923
  demeaned_times = times - times.mean()
925
924
  T = (demeaned_times.values[:, None] * resids.values).sum(0) ** 2 / (
926
- n_deaths * (fitted_cox_model.standard_errors_ ** 2) * (demeaned_times ** 2).sum()
925
+ n_deaths * (fitted_cox_model.standard_errors_**2) * (demeaned_times**2).sum()
927
926
  )
928
927
  return T
929
928
 
@@ -1955,3 +1955,54 @@ class CovariateParameterMappings:
1955
1955
  design_info = formulaic.ModelSpec.from_spec(formulaic.Formula(formula).get_model_matrix(df))
1956
1956
 
1957
1957
  return design_info
1958
+
1959
+ class LinearAccumulator:
1960
+ """
1961
+ This class represents a linear function F(x), which can be updated iteratively.
1962
+ """
1963
+ def __init__(self):
1964
+ """
1965
+ Initializes F(x) as 0.
1966
+ """
1967
+ self.const_term: float = 0.0
1968
+ self.linear_term: float = 0.0
1969
+
1970
+ def add_linear_term(self, a: float, b: float) -> None:
1971
+ """
1972
+ Adds a * (x - b) to F(x).
1973
+ """
1974
+ self.const_term -= a * b
1975
+ self.linear_term += a
1976
+
1977
+ def evaluate(self, x: float) -> float:
1978
+ """
1979
+ Evaluates F(x) at the given value of x.
1980
+ """
1981
+ return self.const_term + self.linear_term * x
1982
+
1983
+ class QuadraticAccumulator:
1984
+ """
1985
+ This class represents a quadratic function F(x), which can be updated iteratively.
1986
+ """
1987
+ def __init__(self):
1988
+ """
1989
+ Initializes F(x) as 0.
1990
+ """
1991
+ self.const_term: float = 0.0
1992
+ self.linear_term: float = 0.0
1993
+ self.quadratic_term: float = 0.0
1994
+
1995
+ def add_quadratic_term(self, a: float, b: float) -> None:
1996
+ """
1997
+ Adds a * (x - b)^2 to F(x).
1998
+ """
1999
+ # a * (x - b)^2 = a * x^2 + (- 2 * a * b) * x + a * b^2
2000
+ self.const_term += a * (b ** 2)
2001
+ self.linear_term -= 2 * a * b
2002
+ self.quadratic_term += a
2003
+
2004
+ def evaluate(self, x: float) -> float:
2005
+ """
2006
+ Evaluates F(x) at the given value of x.
2007
+ """
2008
+ return self.const_term + self.linear_term * x + self.quadratic_term * (x ** 2)
lifelines/version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from __future__ import unicode_literals
3
3
 
4
- __version__ = "0.29.0"
4
+ __version__ = "0.30.1"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: lifelines
3
- Version: 0.29.0
3
+ Version: 0.30.1
4
4
  Summary: Survival analysis in Python, including Kaplan Meier, Nelson Aalen and regression
5
5
  Home-page: https://github.com/CamDavidsonPilon/lifelines
6
6
  Author: Cameron Davidson-Pilon
@@ -16,13 +16,24 @@ Classifier: Topic :: Scientific/Engineering
16
16
  Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: numpy <2.0,>=1.14.0
20
- Requires-Dist: scipy >=1.7.0
21
- Requires-Dist: pandas >=2.1
22
- Requires-Dist: matplotlib >=3.0
23
- Requires-Dist: autograd >=1.5
24
- Requires-Dist: autograd-gamma >=0.3
25
- Requires-Dist: formulaic >=0.2.2
19
+ Requires-Dist: numpy>=1.14.0
20
+ Requires-Dist: scipy>=1.7.0
21
+ Requires-Dist: pandas<3.0,>=2.1
22
+ Requires-Dist: matplotlib>=3.0
23
+ Requires-Dist: autograd>=1.5
24
+ Requires-Dist: autograd-gamma>=0.3
25
+ Requires-Dist: formulaic>=0.2.2
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: classifier
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: home-page
32
+ Dynamic: license
33
+ Dynamic: license-file
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
26
37
 
27
38
  ![](http://i.imgur.com/EOowdSD.png)
28
39
 
@@ -2,9 +2,9 @@ lifelines/__init__.py,sha256=F_sKrawq6L4GwTPgOu4FjoGUKQ2gfelAVIQOW1Ee8Ao,2241
2
2
  lifelines/calibration.py,sha256=Luii7bkJ2YB0jpuOYYhI22aUyEc1gLsS10Pno6Sqo98,4113
3
3
  lifelines/exceptions.py,sha256=8T1vQuI6Fnf_5OfiJahksn5Soe-SmU9Y2IA7HYen460,577
4
4
  lifelines/generate_datasets.py,sha256=nwGVpkcVRKH70N8z0Z-y7GgetX8suZZ1FFmdjOB8tBs,10188
5
- lifelines/plotting.py,sha256=sQmwpSziHzVQoWoe_gll4LInrjg-E4FpeWMp07wurNo,35069
6
- lifelines/statistics.py,sha256=cOszUYz87elnbTAt6V3fTrHwPjB9HFI1hxjLvKypS6k,35129
7
- lifelines/version.py,sha256=pYOd-rP1moJefUJJ6DbkYBuzORUtOVDOBiCBT13-usg,88
5
+ lifelines/plotting.py,sha256=nlB1mKbsAErzXGcVnAPAqs6KYBkcbi_FE_n3nk12CIo,35397
6
+ lifelines/statistics.py,sha256=cB_l0DSNjiGawidF8ZqbuqMEp_jb0-8Cl-t_PgJpVas,35227
7
+ lifelines/version.py,sha256=zwfIJ0IEYekk81kpAtycuZepE_ivnUj776RFJ9XQGgs,88
8
8
  lifelines/datasets/CuZn-LeftCensoredDataset.csv,sha256=PxTdZcJPPbhtaadpHjhMFVcUxmSn84BuDarujZIJpm4,1996
9
9
  lifelines/datasets/__init__.py,sha256=wiKbbNj-SSrgk_jysTdeQo1ceCmHXKje8WIzwBJAH_E,19977
10
10
  lifelines/datasets/anderson.csv,sha256=nTAtTK8mf0ymU88nKvO2Fj0WL9SE9o4S0GVujmX8Cl4,580
@@ -35,12 +35,12 @@ lifelines/datasets/rossi.csv,sha256=AhRAAXDgfzAVooXtyiAUysDa6KrBJfy6rWQkkOBfiSw,
35
35
  lifelines/datasets/stanford_heart.csv,sha256=HWS9SqJjQ6gDmvxxKCJLR1cOIJ8XKuwTNu4bW8tKWVM,8859
36
36
  lifelines/datasets/static_test.csv,sha256=w2PtSkXknCZfciwqcOZGlA8znBO7jTcq_AJ5e6NStAk,101
37
37
  lifelines/datasets/waltons_dataset.csv,sha256=Fd4UX6tGYxgGhXtH3T-S81wIGIbVohv5yom4aw0kXL8,2449
38
- lifelines/fitters/__init__.py,sha256=a3ACmN8KANdg7uyZ36lSIMvUx0rZKB3HhvHdTgbQfP0,151648
39
- lifelines/fitters/aalen_additive_fitter.py,sha256=xca1uoNbuPS2YoGQ73GYa5JLZTLCt9otJPhhi2AJm4A,21526
40
- lifelines/fitters/aalen_johansen_fitter.py,sha256=w_2MV7Bbtr0swJ0VdySqirhlGsjbYyqduRx9iLKd6XA,14172
38
+ lifelines/fitters/__init__.py,sha256=BH3z__XvjkQ4JDr2H9W0WpNYlGxp2p-vYrqspQmnIwk,151829
39
+ lifelines/fitters/aalen_additive_fitter.py,sha256=uDHl-O3Umg9EdLqC3pOnEK3UdtOdqleBmvRSC68F888,21527
40
+ lifelines/fitters/aalen_johansen_fitter.py,sha256=p2o0xErkroM0XbwZvqO2jO2RlEWJalJ-YKFHQA286jo,14424
41
41
  lifelines/fitters/breslow_fleming_harrington_fitter.py,sha256=_86qU3wMHEyuCKLjhHLERP_ymNnlSvi7chWgi8Kygxg,4293
42
- lifelines/fitters/cox_time_varying_fitter.py,sha256=cZo9opn4OdFajrj6aBxJDhgWvFIUHdsq7jpgMQ0HchU,34670
43
- lifelines/fitters/coxph_fitter.py,sha256=zbmwmO1EyHy-19ijuMkF_RCb7dG_VB7DBH7qArHar6w,136920
42
+ lifelines/fitters/cox_time_varying_fitter.py,sha256=WSEMaPXrNG3REjFHDAr0RoNAqRhVBUhWSLQmcG-9OAM,34697
43
+ lifelines/fitters/coxph_fitter.py,sha256=-IMamyLjZ3fJASxWqiAQicLf1AQAbo7bM0UF69P8pIw,137365
44
44
  lifelines/fitters/crc_spline_fitter.py,sha256=FUaiz4O-Hdke7T5dV8RCl-27oWxrMJLBSXxnRN4QkGQ,3126
45
45
  lifelines/fitters/exponential_fitter.py,sha256=Fbb1rtBOrHb_YxFYidzqXcFw7aWsqet_2vqi7s8WJ4U,2857
46
46
  lifelines/fitters/generalized_gamma_fitter.py,sha256=OiXO9onvYtI2gNvUoxF4mjEjbj7IRZl5R4UZ_RzrSjo,6482
@@ -59,14 +59,14 @@ lifelines/fitters/piecewise_exponential_regression_fitter.py,sha256=kdnsm2oE1i_S
59
59
  lifelines/fitters/spline_fitter.py,sha256=TnkXPBabgZVqtI90T1-gm6C8k73WhQMrhbEAZw1OX0c,4214
60
60
  lifelines/fitters/weibull_aft_fitter.py,sha256=6wtU499AvXxZAE9PdnNQnbzh_NpPcdAEL6zd3xRV8hU,7772
61
61
  lifelines/fitters/weibull_fitter.py,sha256=CcII_V5ns00jP5sqv0dn8Yo0T3kdyc4Rkpb2bBuTvjU,3771
62
- lifelines/utils/__init__.py,sha256=IIn6YTAh98n8Jb7y1MZcHlAcrmO5XiVcu2nMrfJVMbE,70500
62
+ lifelines/utils/__init__.py,sha256=Z_HJklPsKqzU0APOUr2qgldkYxPwlxgd6VM_Hq8ycCE,71970
63
63
  lifelines/utils/btree.py,sha256=yevaIsGw_tQsGauXmwBHTMgCBjuuMZQgdHa-nCB-q2I,4369
64
64
  lifelines/utils/concordance.py,sha256=hWXrmg1BiK2Hqu9CRzlvkPlnlmZqZcAxH7L1PjaqdC8,12245
65
65
  lifelines/utils/lowess.py,sha256=MMydVcnbxqIgsiNcIgVUFtlFycD7v3ezwEGpituvBHs,2541
66
66
  lifelines/utils/printer.py,sha256=-nXxu02gs0kaKfoQQ65sH-I45tGmgoFeOOIUSEc53iE,5861
67
67
  lifelines/utils/safe_exp.py,sha256=HCCAkwQTx6G2qRC03v9Q_GWqVj8at1Eac1JVrMgS9hg,4350
68
- lifelines-0.29.0.dist-info/LICENSE,sha256=AasDeD139SnTdfXbKgN4BMyMgBlRy9YFs60tNrB4wf0,1079
69
- lifelines-0.29.0.dist-info/METADATA,sha256=JOhlJ11AqPSdC2P1z8KNg_Sh4mhCj9f7ymMBz85cZi8,3187
70
- lifelines-0.29.0.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
71
- lifelines-0.29.0.dist-info/top_level.txt,sha256=3i57Z4mtpc6jWrsW0n-_o9Y7CpzytMTeLMPJBHYAo0o,10
72
- lifelines-0.29.0.dist-info/RECORD,,
68
+ lifelines-0.30.1.dist-info/licenses/LICENSE,sha256=AasDeD139SnTdfXbKgN4BMyMgBlRy9YFs60tNrB4wf0,1079
69
+ lifelines-0.30.1.dist-info/METADATA,sha256=T_SD5iljKfXGSb5GzkIuIaqHStef6SXzBRgNBzZYvnY,3416
70
+ lifelines-0.30.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
71
+ lifelines-0.30.1.dist-info/top_level.txt,sha256=3i57Z4mtpc6jWrsW0n-_o9Y7CpzytMTeLMPJBHYAo0o,10
72
+ lifelines-0.30.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5