balance.sample_frame¶
SampleFrame: an explicit-role DataFrame container for the Balance library.
Stores covariates, weights, outcomes, outcomes_hat, and ignored columns with explicit role metadata, replacing the inference-by-exclusion pattern used in the legacy Sample class.
- class balance.sample_frame.SampleFrame[source]¶
A DataFrame container with explicit column-role metadata.
SampleFrame stores data as a single internal pd.DataFrame but with explicit metadata tracking which columns belong to which role: covars (X), weights (W), outcomes (Y), outcomes_hat (Y_hat), ignored.
Must be constructed via SampleFrame.from_frame() or SampleFrame.from_sample().
- Mutability:
SampleFrame is mostly-immutable at the data level. The underlying DataFrame and column-role assignments are set at construction time and are not replaced afterwards. All data-access properties (e.g.
df_covars,df_weights) return copies, so callers cannot mutate internal state through the returned objects.Controlled mutation points (methods that intentionally modify the instance in-place):
set_active_weight()— changes which weight column is active.add_weight_column()— appends a new weight column to the frame.set_weight_metadata()— updates weight provenance metadata.
These mutations are intentional and expected as part of normal usage (e.g. after calling
BalanceFrame.adjust()). Outside of these methods the object behaves as immutable.
- add_outcomes_hat_column(name: str, values: Series, metadata: dict[str, Any] | None = None) None[source]¶
Attach a predicted-outcome (Y_hat) column to the SampleFrame.
Mirrors
add_weight_column(): the column is appended to the internal DataFrame in place, registered under theoutcomes_hatrole, and optionally associated with provenance metadata (stored in_prediction_metadata). Because the column takes theoutcomes_hatrole, it is not treated as a covariate.By convention, predicted-outcome columns are named
"<outcome>_hat"(e.g."happiness_hat"). Alogging.warningis emitted — but no error raised — when name does not end in_hat.- Parameters:
name (str) – Name for the new outcomes_hat column.
values (pd.Series) – Predicted values. Must match the DataFrame length, unless it is a shorter
pd.Series— in which case values are aligned by index and missing rows are filled with NaN.metadata (dict, optional) – Provenance metadata for the new column (e.g. the fitting method or learner).
- Raises:
ValueError – If name is already an outcomes_hat column, if name already exists in the DataFrame, or if values is longer than the DataFrame (or is a non-Series with a different length).
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25, 30, 35, 40], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.add_outcomes_hat_column("happiness_hat", ... pd.Series([52., 58., 68., 79.])) >>> sf.df_outcomes_hat["happiness_hat"].tolist() [52.0, 58.0, 68.0, 79.0] >>> list(sf.df_covars.columns) ['age']
- add_weight_column(name: str, values: Series, metadata: dict[str, Any] | None = None) None[source]¶
Add a new weight column to the SampleFrame.
The column is appended to the internal DataFrame and registered as a weight column. Optionally associates provenance metadata.
- Parameters:
name (str) – Name for the new weight column.
values (pd.Series) – Weight values. Must match the DataFrame length, unless it is a shorter
pd.Series— in which case values are aligned by index and missing rows are filled with NaN (this supports adjustment functions that drop rows internally, e.g.,na_action="drop"). Note: this column is a history column, not the active weight — the active weight is set separately viaset_weights().metadata (dict, optional) – Provenance metadata for the new column.
- Raises:
ValueError – If name is already a registered weight column, if name already exists in the DataFrame as a non-weight column, or if values is longer than the DataFrame or is a non-Series with a different length.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.add_weight_column("w_adj", pd.Series([1.5, 1.5]), ... metadata={"method": "rake"}) >>> sf._column_roles["weights"] ['weight', 'w_adj']
- property covar_columns: list[str]¶
Names of the covariate columns.
Returns a copy so that callers cannot accidentally mutate the internal column-role registry.
- Returns:
Covariate column names.
- Return type:
list[str]
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "age": [25, 30], ... "income": [50000, 60000], "weight": [1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.covar_columns ['age', 'income']
- covars(formula: str | list[str] | None = None) Any[source]¶
Return a
BalanceDFCovarsfor this SampleFrame.Creates a covariate analysis view backed by this SampleFrame, inheriting any linked sources set via
_links.- Parameters:
formula – Optional formula string (or list) for model matrix construction. Passed through to BalanceDFCovars.
- Returns:
Covariate view backed by this SampleFrame.
- Return type:
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame.from_frame( ... pd.DataFrame({"id": [1, 2], "x": [10.0, 20.0], ... "weight": [1.0, 1.0]})) >>> sf.covars().df.columns.tolist() ['x']
- property df: DataFrame¶
Full DataFrame reconstruction.
- property df_covars: DataFrame¶
Covariate columns as a DataFrame.
Returns a copy so that callers cannot accidentally mutate the internal data.
- Returns:
A copy of the covariate columns.
- Return type:
pd.DataFrame
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "age": [25, 30], ... "income": [50000, 60000], "weight": [1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> covars = sf.df_covars >>> covars["age"] = [999, 999] >>> list(sf.df_covars["age"]) # internal data unchanged [25.0, 30.0]
- property df_ignored: DataFrame | None¶
Ignored columns, or None.
Returns a copy so that callers cannot accidentally mutate the internal data.
- Returns:
- A copy of ignored columns, or
None if no ignored columns are registered.
- Return type:
pd.DataFrame | None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0], "region": ["US", "UK"]}) >>> sf = SampleFrame.from_frame(df, ignored_columns=["region"]) >>> m = sf.df_ignored >>> m["region"] = ["XX", "XX"] >>> list(sf.df_ignored["region"]) # internal data unchanged ['US', 'UK']
- property df_outcomes: DataFrame | None¶
Outcome columns, or None if no outcomes.
Returns a copy so that callers cannot accidentally mutate the internal data.
- Returns:
- A copy of outcome columns, or None if
no outcome columns are registered.
- Return type:
pd.DataFrame | None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0], "y": [5, 6]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["y"]) >>> out = sf.df_outcomes >>> out["y"] = [999, 999] >>> list(sf.df_outcomes["y"]) # internal data unchanged [5.0, 6.0]
- property df_outcomes_hat: DataFrame | None¶
Predicted-outcome (Y_hat) columns, or None if none.
Mirrors
df_outcomesfor theoutcomes_hatrole. Returns a copy so that callers cannot accidentally mutate the internal data.- Returns:
- A copy of the outcomes_hat columns, or None
if no outcomes_hat columns are registered.
- Return type:
pd.DataFrame | None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25, 30, 35, 40], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.add_outcomes_hat_column("happiness_hat", ... pd.Series([52., 58., 68., 79.])) >>> sf.df_outcomes_hat["happiness_hat"].tolist() [52.0, 58.0, 68.0, 79.0]
- property df_weights: DataFrame¶
Active weight column as a single-column DataFrame.
Returns a copy so that callers cannot accidentally mutate the internal data.
- Returns:
- A copy of the active weight column, or an empty
DataFrame if no active weight is set.
- Return type:
pd.DataFrame
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> w = sf.df_weights >>> w["weight"] = [999.0, 999.0] >>> list(sf.df_weights["weight"]) # internal data unchanged [1.0, 2.0]
- fit_outcome_model(*, model: OutcomeLearner = 'auto', outcome_columns: list[str] | str | None = None, variables: list[str] | str | None = None, formula: str | list[str] | None = None, transformations: str | dict[str, Any] | None = None, na_action: str = 'add_indicator', use_model_matrix: bool | str = 'auto', weighted: bool = False, calibrate: bool = False, inplace: bool = True) Self[source]¶
Fit an outcome model
ĝ(X) ≈ E[Y|X]on the responders and store it.This is the outcome-modelling counterpart to
fit()(which fits the weighting model). It fits a regressor (continuous outcome) or classifier (binary outcome) per resolved outcome column on this frame’s covariates and observed outcome(s), and stores the resulting model dict (fitted estimators + preprocessing) onoutcome_model. Like sklearn’sfit(), it does not produce predictions — callpredict_outcomes()(orfit_predict_outcomes()) to write the<outcome>_hatcolumns.The fit is unweighted by default (
weighted=False): the outcome model estimatesE[Y|X]and is usually best left unbiased by the design weights. Passweighted=Trueto fit with the frame’s currently-applied weight (weighted least squares / weighted boosting), aligned to the covariate index before it is passed through. Rows whose outcomeYis missing (NaN) are dropped before fitting — the covariates and weights are aligned to the retained rows, so the fit uses only complete outcome observations. Re-fitting drops any<outcome>_hatcolumns left by a previouspredict_outcomes()so a stale prediction cannot linger against a newly-fit model.- Parameters:
model –
"auto"(aHistGradientBoostingregressor/classifier chosen by outcome type), a single sklearn estimator (cloned per outcome column — one estimator type only when the outcomes are mixed), a{"_discrete": clf, "_continuous": reg}type map, or a{outcome_column: estimator}column map.outcome_columns – Outcome column name(s) to model. Defaults to all of this frame’s
outcome_columns; raises if none exist.variables – Covariate column name(s) to use as the model inputs
X. Defaults toNone(all of this frame’s covariates); pass a subset (validated against the covariate role) to restrict the model to those columns.formula – Optional patsy formula(s) forwarded to the one-hot path.
transformations – Reserved for parity with IPW; must be
None(the replay-safe default) — a non-Nonevalue raises.na_action – Missing-value handling for the design matrix; only
"add_indicator"(default) is supported ("drop"raises).use_model_matrix –
"auto"(default) picks the native-categorical path for tree/boosting learners on scikit-learn >= 1.4 and the one-hot + scaler path otherwise; passTrue/Falseto force.weighted – When
True, fit with the frame’s currently-applied weight (weighted least squares / weighted boosting). Defaults toFalse— the outcome model predictsE[Y|X]and is usually best left unweighted. A weighted fit whose estimator’sfitdoes not acceptsample_weightraisesTypeError.calibrate – When
True, wrap each classifier inCalibratedClassifierCV(binary outcomes only).inplace – If
True(default), mutate this frame (store the model) and returnself; ifFalse, return a new copy with the model stored and leaveselfuntouched — mirroringfit().
- Returns:
The frame with the fitted outcome model stored (
selfwheninplace, else a new copy).- Raises:
ValueError – If there are no outcome columns to fit (and none are passed), if a requested outcome/variable column is not registered, or for the underlying
fit_outcome_modelerrors (na_action="drop", non-Nonetransformations, amodelcolumn map missing an outcome column, a single estimator for mixed-type outcomes, etc.).TypeError – If
weighted=Truebut the resolved estimator’sfitdoes not acceptsample_weight.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25.0, 30.0, 35.0, 40.0], ... "happiness": [50.0, 55.0, 65.0, 80.0], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["happiness"]) >>> sf.fit_outcome_model() <balance.sample_frame.SampleFrame object at ...> >>> sf.outcome_model["method"] 'outcome_model' >>> sf.df_outcomes_hat is None # fit does NOT persist Ŷ True
- fit_predict_outcomes(*, populate: bool = True, **fit_kwargs: Any) DataFrame[source]¶
Fit an outcome model then predict on this frame, in one call.
Convenience wrapper mirroring sklearn’s
fit_predict: it callsfit_outcome_model()(in place) with**fit_kwargsand thenpredict_outcomes()on this frame, persisting<outcome>_hatwhenpopulate=True(the default).- Parameters:
populate – When
True(default), persist the predictions onto this frame as<outcome>_hatcolumns.**fit_kwargs – Keyword arguments forwarded to
fit_outcome_model()(e.g.model,outcome_columns,variables,weighted).inplaceis alwaysTruehere.
- Returns:
- The predictions, one
"<outcome>_hat"column per fitted outcome.
- The predictions, one
- Return type:
pd.DataFrame
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25.0, 30.0, 35.0, 40.0], ... "happiness": [50.0, 55.0, 65.0, 80.0], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["happiness"]) >>> preds = sf.fit_predict_outcomes() >>> list(preds.columns) ['happiness_hat'] >>> sf.outcome_model["method"] 'outcome_model'
- classmethod from_frame(df: DataFrame, id_column: str | None = None, covar_columns: list[str] | None = None, weight_column: str | None = None, outcome_columns: list[str] | tuple[str, ...] | str | None = None, outcomes_hat_columns: list[str] | tuple[str, ...] | str | None = None, ignored_columns: list[str] | tuple[str, ...] | str | None = None, check_id_uniqueness: bool = True, standardize_types: bool = True, use_deepcopy: bool = True, id_column_candidates: list[str] | tuple[str, ...] | str | None = None) SampleFrame[source]¶
Create a SampleFrame from a pandas DataFrame with auto-detection.
Infers id, weight, and covariate columns from column names when not explicitly provided. Validates the data (e.g., unique IDs, non-negative weights) and standardizes dtypes (Int64 -> float64, pd.NA -> np.nan).
- Parameters:
df (pd.DataFrame) – The input DataFrame containing survey or observational data.
id_column (str, optional) – Name of the column to use as row identifier. If None, guessed from common names (
"id","ID", etc.).covar_columns (list of str, optional) – Explicit list of covariate column names. If None, inferred by exclusion (all columns minus id, weight, outcome, outcomes_hat, and ignored columns).
weight_column (str, optional) – Name of the column containing sampling weights. If None, guesses
"weight"/"weights"or creates one filled with 1.0.outcome_columns (list of str or str, optional) – Column names to treat as outcome variables.
outcomes_hat_columns (list of str or str, optional) – Column names to treat as predicted-outcome (Y_hat) variables.
ignored_columns (list of str or str, optional) – Column names to ignore (excluded from covariates).
check_id_uniqueness (bool) – Whether to verify id uniqueness. Defaults to True.
standardize_types (bool) – Whether to standardize dtypes. Defaults to True.
use_deepcopy (bool) – Whether to deep-copy the input DataFrame. Defaults to True.
id_column_candidates (list of str, optional) – Candidate id column names to try when
id_columnis None.
- Returns:
A validated SampleFrame with standardized dtypes.
- Return type:
- Raises:
ValueError – If the id column contains nulls or duplicates, if the weight column contains nulls or negative values, or if specified outcome/outcomes_hat/ignore columns are missing from the DataFrame.
Examples
>>> import pandas as pd >>> df = pd.DataFrame({"id": [1, 2, 3], "weight": [1.0, 2.0, 1.5], ... "age": [25, 30, 35], "income": [50000, 60000, 70000]}) >>> sf = SampleFrame.from_frame(df) >>> list(sf.df_covars.columns) ['age', 'income']
- classmethod from_sample(sample: Any) SampleFrame[source]¶
Convert a
Sampleto a SampleFrame.Preserves the Sample’s tabular data and column role assignments: id column, weight column, outcome columns, and ignored columns. Covariate columns are inferred by exclusion, matching the Sample’s own logic.
The internal DataFrame is deep-copied so that the resulting SampleFrame is fully independent of the original Sample.
Warning
Data not preserved in the conversion
The following Sample attributes are not carried over:
_adjustment_model— the fitted model dictionary stored byadjust()._links— references totarget,unadjusted, and other linked Samples (used byBalanceDFfor comparative display).Column ordering may differ after a round-trip (
Sample → SampleFrame → Sample), since SampleFrame stores columns grouped by role rather than preserving the original DataFrame column order.
- Parameters:
sample – A
Sampleinstance.- Returns:
- A new SampleFrame mirroring the Sample’s data and
column roles.
- Return type:
- Raises:
TypeError – If sample is not a Sample instance.
Examples
>>> import pandas as pd >>> from balance.sample_class import Sample >>> from balance.sample_frame import SampleFrame >>> s = Sample.from_frame( ... pd.DataFrame({"id": [1, 2], "x": [10.0, 20.0], "weight": [1.0, 2.0]})) >>> sf = SampleFrame.from_sample(s) >>> list(sf.df_covars.columns) ['x']
- property id_column: str¶
Name of the ID column.
Note
In balance 0.20.0,
id_columnwas changed from returning ID data (pd.Series) to returning the column name (str), for consistency withweight_column. If you need ID data, useid_series.- Returns:
The ID column name.
- Return type:
str
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.id_column 'id'
- property id_series: Series¶
The ID column as a Series.
Returns a copy so that callers cannot accidentally mutate the internal data.
- Returns:
A copy of the ID column.
- Return type:
pd.Series
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> ids = sf.id_series >>> ids.iloc[0] = "MUTATED" >>> sf.id_series.iloc[0] # internal data unchanged '1'
- property ignored_columns: list[str]¶
Names of the ignored columns.
Returns a copy so that callers cannot accidentally mutate the internal column-role registry.
- Returns:
Ignored column names (empty list if none).
- Return type:
list[str]
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0], "region": ["US", "UK"]}) >>> sf = SampleFrame.from_frame(df, ignored_columns=["region"]) >>> sf.ignored_columns ['region']
- property outcome_columns: list[str]¶
Names of the outcome columns.
Returns a copy so that callers cannot accidentally mutate the internal column-role registry.
- Returns:
Outcome column names (empty list if none).
- Return type:
list[str]
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0], "y": [5, 6]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["y"]) >>> sf.outcome_columns ['y']
- property outcome_model: dict[str, Any] | None¶
The fitted outcome-model dictionary, or None if not fit.
Mirrors
model(which holds the weighting model) for the outcome-modelling axis. The dict is produced byfit_outcome_model()and consumed bypredict_outcomes(); its keys are documented onbalance.outcome_models.fit_outcome_model()("method","fit","X_matrix_columns","perf", …).- Returns:
- The stored
_outcome_modeldict, or Nonewhen no outcome model has been fit.
- The stored
- Return type:
dict[str, Any] | None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25.0, 30.0, 35.0, 40.0], ... "happiness": [50.0, 55.0, 65.0, 80.0], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["happiness"]) >>> sf.outcome_model is None True >>> sf.fit_outcome_model() <balance.sample_frame.SampleFrame object at ...> >>> sf.outcome_model["method"] 'outcome_model'
- outcomes() Any | None[source]¶
Return a
BalanceDFOutcomes, or None.Returns
Noneif this SampleFrame has no outcome columns.- Returns:
- Outcome view backed by this SampleFrame,
or
Noneif no outcomes are defined.
- Return type:
BalanceDFOutcomes or None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame.from_frame( ... pd.DataFrame({"id": [1, 2], "x": [10.0, 20.0], ... "y": [1.0, 0.0], "weight": [1.0, 1.0]}), ... outcome_columns=["y"]) >>> sf.outcomes().df.columns.tolist() ['y']
- outcomes_hat() Any | None[source]¶
Return a
BalanceDFOutcomesHat, or None.Returns
Noneif this SampleFrame has no predicted-outcome (outcomes_hat/ Y_hat) columns. When present, the returned view exposes the weighted mean / CI machinery over the Y_hat columns (one column per predicted outcome), mirroringoutcomes().- Returns:
- Predicted-outcome view backed by this
SampleFrame, or
Noneif no outcomes_hat columns are defined.
- Return type:
BalanceDFOutcomesHat or None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25, 30, 35, 40], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.add_outcomes_hat_column("happiness_hat", ... pd.Series([52., 58., 68., 79.])) >>> sf.outcomes_hat().df.columns.tolist() ['happiness_hat'] >>> SampleFrame.from_frame(df).outcomes_hat() is None True
- property outcomes_hat_columns: list[str]¶
Names of the predicted-outcome (Y_hat) columns.
Returns a copy so that callers cannot accidentally mutate the internal column-role registry.
- Returns:
outcomes_hat column names (empty list if none).
- Return type:
list[str]
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 1.0], "p_y": [0.3, 0.7]}) >>> sf = SampleFrame.from_frame(df, outcomes_hat_columns=["p_y"]) >>> sf.outcomes_hat_columns ['p_y']
- predict_outcomes(*, data: SampleFrame | None = None, populate: bool | None = None) DataFrame[source]¶
Predict
outcomes_hatfrom the stored model, optionally persisting.Requires a model fit by
fit_outcome_model(). Predictions are produced on this frame’s covariates (or ondata’s covariates when aSampleFrameis passed viadata=) by replaying the model’s stored preprocessing. The returned DataFrame has one column per fitted outcome, named"<outcome>_hat".When
populateisTrue, the predicted columns are written onto this frame viaadd_outcomes_hat_column()(a same-named Ŷ column is dropped and re-added).- Parameters:
data – Optional
SampleFramewhose covariates to score. Defaults toNone, meaning predict on this frame’s own covariates. When scoring a different frame, preferpopulate=False: persisting predictions row-indexed bydataonto this frame would row-misalign (they are reindexed to this frame, NaN-padding or dropping non-matching rows).populate – Whether to persist the predictions onto this frame as
<outcome>_hatcolumns. Defaults toTruewhen scoring this frame (data=None) andFalsewhendata=is given, since a different frame’s row index would misalign onto this one.
- Returns:
- The predictions, one
"<outcome>_hat"column per fitted outcome, indexed by the scored covariate rows.
- The predictions, one
- Return type:
pd.DataFrame
- Raises:
ValueError – If no outcome model has been fit on this frame.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2", "3", "4"], ... "age": [25.0, 30.0, 35.0, 40.0], ... "happiness": [50.0, 55.0, 65.0, 80.0], ... "weight": [1.0, 1.0, 1.0, 1.0]}) >>> sf = SampleFrame.from_frame(df, outcome_columns=["happiness"]) >>> _ = sf.fit_outcome_model() >>> preds = sf.predict_outcomes() >>> list(preds.columns) ['happiness_hat'] >>> "happiness_hat" in sf.outcomes_hat_columns True
- rename_weight_column(old_name: str, new_name: str) None[source]¶
Rename a weight column in-place.
Renames the column in the DataFrame, updates the column roles list, active weight pointer, and weight metadata.
- Parameters:
old_name – Current name of the weight column.
new_name – New name for the weight column.
- Raises:
ValueError – If old_name is not a registered weight column, or if new_name already exists in the DataFrame.
- set_active_weight(column_name: str) None[source]¶
Set which weight column is the active one.
The active weight column is the one returned by
df_weights.- Parameters:
column_name (str) – Must be a registered weight column.
- Raises:
ValueError – If column_name is not a weight column.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame._create( ... df=pd.DataFrame({"id": [1], "x": [10], "w1": [1.0], "w2": [2.0]}), ... id_column="id", covar_columns=["x"], ... weight_columns=["w1", "w2"]) >>> sf.set_active_weight("w2") >>> list(sf.df_weights.columns) ['w2']
- set_weight_metadata(column: str, metadata: dict[str, Any]) None[source]¶
Store provenance metadata for a weight column.
Metadata is an arbitrary dict that can track adjustment method, hyperparameters, timestamps, or any other provenance information relevant to how the weight column was computed.
- Parameters:
column (str) – Name of the weight column.
metadata (dict) – Arbitrary metadata dict (e.g. method name, hyperparameters, timestamp).
- Raises:
ValueError – If column is not a registered weight column.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.set_weight_metadata("weight", {"method": "ipw"}) >>> sf.weight_metadata() {'method': 'ipw'}
- set_weights(weights: Series | float | None, *, use_index: bool = False) None[source]¶
Replace the active weight column values.
This is the canonical weight-update method for balance objects. Both
SampleFrameandBalanceFrameuse this implementation (BalanceFrame delegates here). It also satisfies theBalanceDFSourceprotocol and is used byBalanceDFWeights.trim()to update weight values after trimming.If weights is a float, all rows are set to that value. If None, all rows are set to 1.0. If a Series, behavior depends on use_index:
use_index=False(default): the Series must have the same length as the DataFrame; values are assigned positionally.use_index=True: values are aligned by index. Rows whose index is missing from weights are set to NaN (pandas index-alignment semantics), and a warning is emitted.
All weight values are cast to float64.
- Parameters:
weights – New weight values — a Series, scalar, or None.
use_index – If True, align a Series by index instead of requiring an exact length match.
- Raises:
ValueError – If no active weight column is set, or if
use_index=Falseand a Series has a different length than the DataFrame.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": [1, 2], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.set_weights(pd.Series([3.0, 4.0])) >>> sf.weight_series.tolist() [3.0, 4.0]
- trim(ratio: float | int | None = None, percentile: float | tuple[float, float] | None = None, keep_sum_of_weights: bool = True, target_sum_weights: float | int | np.floating | None = None, *, inplace: bool = False) Self[source]¶
Trim extreme weights using mean-ratio clipping or percentile winsorization.
Delegates to
trim_weights()for the computation, then writes the result back viaset_weights(). A weight history column (weight_trimmed_N) is added so the pre-trim values are preserved.- Parameters:
ratio – Mean-ratio upper bound. Mutually exclusive with percentile.
percentile – Percentile(s) for winsorization. Mutually exclusive with ratio.
keep_sum_of_weights – Whether to rescale after trimming to preserve the original sum of weights.
target_sum_weights – If provided, rescale trimmed weights so their sum equals this numeric target value. (This is a general-purpose rescaling parameter — not related to the “target population” concept in BalanceFrame.)
inplace – If True, mutate this SampleFrame and return it. If False (default), return a new SampleFrame with trimmed weights and the original left untouched.
- Returns:
The SampleFrame with trimmed weights (self if inplace, else a new copy).
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame.from_frame( ... pd.DataFrame({"id": [1, 2, 3], "weight": [1.0, 2.0, 100.0]})) >>> sf2 = sf.trim(ratio=2) >>> sf2.weight_series.max() < 100.0 True >>> "weight_trimmed_1" in sf2._df.columns True
- property weight_column: str | None¶
Name of the currently active weight column, or None.
Note
In balance 0.19.0,
weight_columnwas changed from returning weight data (pd.Series) to returning the column name (str). If you need weight data, useweight_series.- Returns:
The active weight column name.
- Return type:
str | None
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.weight_column 'weight'
- property weight_columns_all: list[str]¶
Names of all registered weight columns.
Returns a copy so that callers cannot accidentally mutate the internal column-role registry.
- Returns:
Weight column names.
- Return type:
list[str]
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame._create( ... df=pd.DataFrame({"id": [1], "x": [10], "w1": [1.0], "w2": [2.0]}), ... id_column="id", covar_columns=["x"], ... weight_columns=["w1", "w2"]) >>> sf.weight_columns_all ['w1', 'w2']
- weight_metadata(column: str | None = None) dict[str, Any][source]¶
Retrieve metadata for a weight column.
- Parameters:
column (str, optional) – Weight column name. Defaults to the active weight column.
- Returns:
The metadata dict, or an empty dict if none was set.
- Return type:
dict
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": ["1", "2"], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.weight_metadata() {}
- property weight_series: Series¶
Active weight column as a Series (BalanceDFSource protocol).
Returns the active weight column values as a
pd.Series. This is the thin protocol-level accessor used byBalanceDFand its subclasses. Unlikedf_weightswhich returns a single-column DataFrame, this returns a plain Series.- Returns:
The active weight column values.
- Return type:
pd.Series
- Raises:
ValueError – If no active weight column is set.
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> df = pd.DataFrame({"id": [1, 2], "x": [10, 20], ... "weight": [1.0, 2.0]}) >>> sf = SampleFrame.from_frame(df) >>> sf.weight_series.tolist() [1.0, 2.0]
- weights() Any[source]¶
Return a
BalanceDFWeightsfor this SampleFrame.Creates a weight analysis view backed by this SampleFrame, inheriting any linked sources set via
_links.- Returns:
Weight view backed by this SampleFrame.
- Return type:
Examples
>>> import pandas as pd >>> from balance.sample_frame import SampleFrame >>> sf = SampleFrame.from_frame( ... pd.DataFrame({"id": [1, 2], "x": [10.0, 20.0], ... "weight": [1.0, 2.0]})) >>> sf.weights().df.columns.tolist() ['weight']