# Path: sksurv/util.py
# def check_y_survival(y_or_event, *args, allow_all_censored=False):
#     """Check that array correctly represents an outcome for survival analysis.
# 
#     Parameters
#     ----------
#     y_or_event : structured array with two fields, or boolean array
#         If a structured array, it must contain the binary event indicator
#         as first field, and time of event or time of censoring as
#         second field. Otherwise, it is assumed that a boolean array
#         representing the event indicator is passed.
# 
#     *args : list of array-likes
#         Any number of array-like objects representing time information.
#         Elements that are `None` are passed along in the return value.
# 
#     allow_all_censored : bool, optional, default: False
#         Whether to allow all events to be censored.
# 
#     Returns
#     -------
#     event : array, shape=[n_samples,], dtype=bool
#         Binary event indicator.
# 
#     time : array, shape=[n_samples,], dtype=float
#         Time of event or censoring.
#     """
#     if len(args) == 0:
#         y = y_or_event
# 
#         if not isinstance(y, numpy.ndarray) or y.dtype.fields is None or len(y.dtype.fields) != 2:
#             raise ValueError('y must be a structured array with the first field'
#                              ' being a binary class event indicator and the second field'
#                              ' the time of the event/censoring')
# 
#         event_field, time_field = y.dtype.names
#         y_event = y[event_field]
#         time_args = (y[time_field],)
#     else:
#         y_event = numpy.asanyarray(y_or_event)
#         time_args = args
# 
#     event = check_array(y_event, ensure_2d=False)
#     if not numpy.issubdtype(event.dtype, numpy.bool_):
#         raise ValueError('elements of event indicator must be boolean, but found {0}'.format(event.dtype))
# 
#     if not (allow_all_censored or numpy.any(event)):
#         raise ValueError('all samples are censored')
# 
#     return_val = [event]
#     for i, yt in enumerate(time_args):
#         if yt is None:
#             return_val.append(yt)
#             continue
# 
#         yt = check_array(yt, ensure_2d=False)
#         if not numpy.issubdtype(yt.dtype, numpy.number):
#             raise ValueError('time must be numeric, but found {} for argument {}'.format(yt.dtype, i + 2))
# 
#         return_val.append(yt)
# 
#     return tuple(return_val)


import numpy
from sklearn.base import BaseEstimator
from sklearn.utils.validation import check_array, check_consistent_length, check_is_fitted
from .util import check_y_survival
    reverse : bool, optional, default: False
        Whether to estimate the censoring distribution.
        When there are ties between times at which events are observed,
        then events come first and are subtracted from the denominator.
        Only available for right-censored data, i.e. `time_enter` must
        be None.

    Returns
    -------
    time : array, shape = (n_times,)
        Unique times.

    prob_survival : array, shape = (n_times,)
        Survival probability at each unique time point.
        If `time_enter` is provided, estimates are conditional probabilities.

    Examples
    --------
    Creating a Kaplan-Meier curve:

    >>> x, y = kaplan_meier_estimator(event, time)
    >>> plt.step(x, y, where="post")
    >>> plt.ylim(0, 1)
    >>> plt.show()

    References
    ----------
    .. [1] Kaplan, E. L. and Meier, P., "Nonparametric estimation from incomplete observations",
           Journal of The American Statistical Association, vol. 53, pp. 457-481, 1958.
    """

# Path: sksurv/util.py
# def check_y_survival(y_or_event, *args, allow_all_censored=False):
#     """Check that array correctly represents an outcome for survival analysis.
# 
#     Parameters
#     ----------
#     y_or_event : structured array with two fields, or boolean array
#         If a structured array, it must contain the binary event indicator
#         as first field, and time of event or time of censoring as
#         second field. Otherwise, it is assumed that a boolean array
#         representing the event indicator is passed.
# 
#     *args : list of array-likes
#         Any number of array-like objects representing time information.
#         Elements that are `None` are passed along in the return value.
# 
#     allow_all_censored : bool, optional, default: False
#         Whether to allow all events to be censored.
# 
#     Returns
#     -------
#     event : array, shape=[n_samples,], dtype=bool
#         Binary event indicator.
# 
#     time : array, shape=[n_samples,], dtype=float
#         Time of event or censoring.
#     """
#     if len(args) == 0:
#         y = y_or_event
# 
#         if not isinstance(y, numpy.ndarray) or y.dtype.fields is None or len(y.dtype.fields) != 2:
#             raise ValueError('y must be a structured array with the first field'
#                              ' being a binary class event indicator and the second field'
#                              ' the time of the event/censoring')
# 
#         event_field, time_field = y.dtype.names
#         y_event = y[event_field]
#         time_args = (y[time_field],)
#     else:
#         y_event = numpy.asanyarray(y_or_event)
#         time_args = args
# 
#     event = check_array(y_event, ensure_2d=False)
#     if not numpy.issubdtype(event.dtype, numpy.bool_):
#         raise ValueError('elements of event indicator must be boolean, but found {0}'.format(event.dtype))
# 
#     if not (allow_all_censored or numpy.any(event)):
#         raise ValueError('all samples are censored')
# 
#     return_val = [event]
#     for i, yt in enumerate(time_args):
#         if yt is None:
#             return_val.append(yt)
#             continue
# 
#         yt = check_array(yt, ensure_2d=False)
#         if not numpy.issubdtype(yt.dtype, numpy.number):
#             raise ValueError('time must be numeric, but found {} for argument {}'.format(yt.dtype, i + 2))
# 
#         return_val.append(yt)
# 
#     return tuple(return_val)


# Path: sksurv/nonparametric.py
import numpy
from sklearn.base import BaseEstimator
from sklearn.utils.validation import check_array, check_consistent_length, check_is_fitted
from .util import check_y_survival

    reverse : bool, optional, default: False
        Whether to estimate the censoring distribution.
        When there are ties between times at which events are observed,
        then events come first and are subtracted from the denominator.
        Only available for right-censored data, i.e. `time_enter` must
        be None.

    Returns
    -------
    time : array, shape = (n_times,)
        Unique times.

    prob_survival : array, shape = (n_times,)
        Survival probability at each unique time point.
        If `time_enter` is provided, estimates are conditional probabilities.

    Examples
    --------
    Creating a Kaplan-Meier curve:

    >>> x, y = kaplan_meier_estimator(event, time)
    >>> plt.step(x, y, where="post")
    >>> plt.ylim(0, 1)
    >>> plt.show()

    References
    ----------
    .. [1] Kaplan, E. L. and Meier, P., "Nonparametric estimation from incomplete observations",
           Journal of The American Statistical Association, vol. 53, pp. 457-481, 1958.
    """

    event, time_enter, time_exit = check_y_survival(event, time_enter, time_exit, allow_all_censored=True)