Skip to content

Interoperability

Writing datasets to disk and handing them to other libraries. See Exporting data and Fitting models to the data.

Export

export

Data export utilities for gen_surv.

This module provides helper functions to save generated survival datasets in various formats.

export_dataset

export_dataset(
    df: DataFrame, path: str, fmt: str | None = None
) -> None

Save a DataFrame to disk.

Parameters:

Name Type Description Default
df DataFrame

DataFrame containing survival data.

required
path str

File path to write to. The extension is used to infer the format when fmt is None.

required
fmt ('csv', 'json', 'feather', 'rds')

Format to use. If omitted, inferred from path.

"csv"

Raises:

Type Description
ChoiceError

If the format is not one of the supported types.

Source code in gen_surv/export.py
def export_dataset(df: pd.DataFrame, path: str, fmt: str | None = None) -> None:
    """Save a DataFrame to disk.

    Parameters
    ----------
    df : pd.DataFrame
        DataFrame containing survival data.
    path : str
        File path to write to. The extension is used to infer the format
        when ``fmt`` is ``None``.
    fmt : {"csv", "json", "feather", "rds"}, optional
        Format to use. If omitted, inferred from ``path``.

    Raises
    ------
    ChoiceError
        If the format is not one of the supported types.
    """
    if fmt is None:
        fmt = os.path.splitext(path)[1].lstrip(".").lower()

    ensure_in_choices(fmt, "fmt", {"csv", "json", "feather", "ft", "rds"})

    if fmt == "csv":
        df.to_csv(path, index=False)
    elif fmt == "json":
        df.to_json(path, orient="table")
    elif fmt in {"feather", "ft"}:
        df.reset_index(drop=True).to_feather(path)
    elif fmt == "rds":
        try:
            import pyreadr  # type: ignore
        except ModuleNotFoundError as exc:  # pragma: no cover - optional dependency
            raise ModuleNotFoundError(
                "pyreadr is required for RDS export; install the 'pyreadr' package."
            ) from exc
        pyreadr.write_rds(path, df.reset_index(drop=True))

scikit-survival

integration

Integration utilities for interfacing with scikit-survival.

to_sksurv

to_sksurv(
    df: DataFrame,
    time_col: str = "time",
    event_col: str = "status",
) -> ndarray

Convert a pandas DataFrame to a scikit-survival structured array.

Parameters:

Name Type Description Default
df DataFrame

DataFrame containing survival data

required
time_col str

Name of the column containing survival times

"time"
event_col str

Name of the column containing event indicators (0/1 or boolean)

"status"

Returns:

Name Type Description
y structured array

Structured array suitable for scikit-survival functions

Raises:

Type Description
ImportError

If scikit-survival is not installed

ValueError

If the DataFrame is empty or columns are missing

Source code in gen_surv/integration.py
def to_sksurv(
    df: pd.DataFrame, time_col: str = "time", event_col: str = "status"
) -> np.ndarray:
    """
    Convert a pandas DataFrame to a scikit-survival structured array.

    Parameters
    ----------
    df : pd.DataFrame
        DataFrame containing survival data
    time_col : str, default "time"
        Name of the column containing survival times
    event_col : str, default "status"
        Name of the column containing event indicators (0/1 or boolean)

    Returns
    -------
    y : structured array
        Structured array suitable for scikit-survival functions

    Raises
    ------
    ImportError
        If scikit-survival is not installed
    ValueError
        If the DataFrame is empty or columns are missing
    """
    if not SKSURV_AVAILABLE:
        raise ImportError("scikit-survival is required but not installed")

    if df.empty:
        # Handle empty DataFrame case by creating a minimal valid structured array
        # This avoids the "event indicator must be binary" error for empty arrays
        return np.array([], dtype=[(event_col, bool), (time_col, float)])

    if time_col not in df.columns:
        raise ValueError(f"Column '{time_col}' not found in DataFrame")
    if event_col not in df.columns:
        raise ValueError(f"Column '{event_col}' not found in DataFrame")

    return Surv.from_dataframe(event_col, time_col, df)

from_sksurv

from_sksurv(
    y: ndarray,
    time_col: str = "time",
    event_col: str = "status",
) -> DataFrame

Convert a scikit-survival structured array to a pandas DataFrame.

Parameters:

Name Type Description Default
y structured array

Structured array from scikit-survival

required
time_col str

Name for the time column in the resulting DataFrame

"time"
event_col str

Name for the event column in the resulting DataFrame

"status"

Returns:

Name Type Description
df DataFrame

DataFrame with time and event columns

Source code in gen_surv/integration.py
def from_sksurv(
    y: np.ndarray, time_col: str = "time", event_col: str = "status"
) -> pd.DataFrame:
    """
    Convert a scikit-survival structured array to a pandas DataFrame.

    Parameters
    ----------
    y : structured array
        Structured array from scikit-survival
    time_col : str, default "time"
        Name for the time column in the resulting DataFrame
    event_col : str, default "status"
        Name for the event column in the resulting DataFrame

    Returns
    -------
    df : pd.DataFrame
        DataFrame with time and event columns
    """
    if not SKSURV_AVAILABLE:
        raise ImportError("scikit-survival is required but not installed")

    if len(y) == 0:
        return pd.DataFrame({time_col: [], event_col: []})

    # Extract field names from structured array
    event_field = y.dtype.names[0]
    time_field = y.dtype.names[1]

    return pd.DataFrame(
        {time_col: y[time_field], event_col: y[event_field].astype(int)}
    )

scikit-learn

sklearn_adapter

BaseEstimatorProto

Bases: Protocol

Protocol capturing the minimal scikit-learn estimator interface.

GenSurvDataGenerator

GenSurvDataGenerator(
    model: ModelType,
    return_type: str = "df",
    **kwargs: object
)

Bases: SklearnBase, BaseEstimatorProto

Scikit-learn compatible wrapper around :func:gen_surv.generate.

Source code in gen_surv/sklearn_adapter.py
def __init__(
    self, model: ModelType, return_type: str = "df", **kwargs: object
) -> None:
    ensure_in_choices(return_type, "return_type", {"df", "dict"})
    self.model = model
    self.return_type = return_type
    self.kwargs = kwargs
get_params
get_params(deep: bool = True) -> dict[str, object]

Return every parameter, including the ones forwarded to the model.

scikit-learn builds this by introspecting __init__, which cannot see through **kwargs. Without the override, clone -- and therefore every pipeline, GridSearchCV and cross_val_score -- would drop the model's parameters and produce an estimator that fails on use.

Parameters:

Name Type Description Default
deep bool

Accepted for interface compatibility. There are no nested estimators, so it makes no difference.

True

Returns:

Type Description
dict[str, object]

model and return_type together with the model's own arguments.

Source code in gen_surv/sklearn_adapter.py
def get_params(self, deep: bool = True) -> dict[str, object]:
    """Return every parameter, including the ones forwarded to the model.

    scikit-learn builds this by introspecting ``__init__``, which cannot see
    through ``**kwargs``. Without the override, ``clone`` -- and therefore
    every pipeline, ``GridSearchCV`` and ``cross_val_score`` -- would drop
    the model's parameters and produce an estimator that fails on use.

    Parameters
    ----------
    deep : bool
        Accepted for interface compatibility. There are no nested
        estimators, so it makes no difference.

    Returns
    -------
    dict[str, object]
        ``model`` and ``return_type`` together with the model's own
        arguments.
    """
    return {"model": self.model, "return_type": self.return_type, **self.kwargs}
set_params
set_params(**params: object) -> 'GenSurvDataGenerator'

Set parameters, whether they belong to the wrapper or the model.

Parameters:

Name Type Description Default
**params object

Any of model, return_type, or an argument of the wrapped generator.

{}

Returns:

Type Description
GenSurvDataGenerator

self, as scikit-learn expects.

Source code in gen_surv/sklearn_adapter.py
def set_params(self, **params: object) -> "GenSurvDataGenerator":
    """Set parameters, whether they belong to the wrapper or the model.

    Parameters
    ----------
    **params
        Any of ``model``, ``return_type``, or an argument of the wrapped
        generator.

    Returns
    -------
    GenSurvDataGenerator
        ``self``, as scikit-learn expects.
    """
    if "model" in params:
        self.model = cast("ModelType", params.pop("model"))
    if "return_type" in params:
        return_type = params.pop("return_type")
        ensure_in_choices(cast(str, return_type), "return_type", {"df", "dict"})
        self.return_type = cast(str, return_type)

    self.kwargs = {**self.kwargs, **params}
    return self