Skip to content

Math Operations

Arithmetic and numeric operations on DataFrame columns.

Overview

Math operations perform arithmetic on numeric columns. They support both scalar operations (column with a constant) and column-wise operations (column with column).

from transformplan import TransformPlan

plan = (
    TransformPlan()
    .math_multiply("price", 1.1)  # 10% increase
    .math_round("price", decimals=2)
    .math_add_columns("subtotal", "tax", "total")
)

Class Reference

MathOps

Mixin providing mathematical operations on columns.

math_add

math_add(column: str, value: Numeric) -> Self

Add a scalar value to a column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_add(self, column: str, value: Numeric) -> Self:
    """Add a scalar value to a column.

    Returns:
        Self for method chaining.
    """
    return self._register(self._math_add, {"column": column, "value": value})

math_subtract

math_subtract(column: str, value: Numeric) -> Self

Subtract a scalar value from a column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_subtract(self, column: str, value: Numeric) -> Self:
    """Subtract a scalar value from a column.

    Returns:
        Self for method chaining.
    """
    return self._register(self._math_subtract, {"column": column, "value": value})

math_multiply

math_multiply(column: str, value: Numeric) -> Self

Multiply a column by a scalar value.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_multiply(self, column: str, value: Numeric) -> Self:
    """Multiply a column by a scalar value.

    Returns:
        Self for method chaining.
    """
    return self._register(self._math_multiply, {"column": column, "value": value})

math_divide

math_divide(column: str, value: Numeric) -> Self

Divide a column by a scalar value.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_divide(self, column: str, value: Numeric) -> Self:
    """Divide a column by a scalar value.

    Returns:
        Self for method chaining.
    """
    return self._register(self._math_divide, {"column": column, "value": value})

math_clamp

math_clamp(
    column: str, lower: Numeric | None = None, upper: Numeric | None = None
) -> Self

Clamp column values to a range.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_clamp(
    self,
    column: str,
    lower: Numeric | None = None,
    upper: Numeric | None = None,
) -> Self:
    """Clamp column values to a range.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_clamp, {"column": column, "lower": lower, "upper": upper}
    )

math_set_min

math_set_min(column: str, min_value: Numeric) -> Self

Set a minimum value for a column (values below are raised to min).

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_set_min(self, column: str, min_value: Numeric) -> Self:
    """Set a minimum value for a column (values below are raised to min).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_set_min, {"column": column, "min_value": min_value}
    )

math_set_max

math_set_max(column: str, max_value: Numeric) -> Self

Set a maximum value for a column (values above are lowered to max).

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_set_max(self, column: str, max_value: Numeric) -> Self:
    """Set a maximum value for a column (values above are lowered to max).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_set_max, {"column": column, "max_value": max_value}
    )

math_abs

math_abs(column: str) -> Self

Take absolute value of a column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_abs(self, column: str) -> Self:
    """Take absolute value of a column.

    Returns:
        Self for method chaining.
    """
    return self._register(self._math_abs, {"column": column})

math_round

math_round(column: str, decimals: int = 0) -> Self

Round a column to specified decimal places.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_round(self, column: str, decimals: int = 0) -> Self:
    """Round a column to specified decimal places.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_round, {"column": column, "decimals": decimals}
    )

math_add_columns

math_add_columns(column_a: str, column_b: str, new_column: str) -> Self

Add two columns together into a new column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_add_columns(self, column_a: str, column_b: str, new_column: str) -> Self:
    """Add two columns together into a new column.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_add_columns,
        {"column_a": column_a, "column_b": column_b, "new_column": new_column},
    )

math_subtract_columns

math_subtract_columns(column_a: str, column_b: str, new_column: str) -> Self

Subtract column_b from column_a into a new column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_subtract_columns(
    self, column_a: str, column_b: str, new_column: str
) -> Self:
    """Subtract column_b from column_a into a new column.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_subtract_columns,
        {"column_a": column_a, "column_b": column_b, "new_column": new_column},
    )

math_multiply_columns

math_multiply_columns(column_a: str, column_b: str, new_column: str) -> Self

Multiply two columns together into a new column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_multiply_columns(
    self, column_a: str, column_b: str, new_column: str
) -> Self:
    """Multiply two columns together into a new column.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_multiply_columns,
        {"column_a": column_a, "column_b": column_b, "new_column": new_column},
    )

math_divide_columns

math_divide_columns(column_a: str, column_b: str, new_column: str) -> Self

Divide column_a by column_b into a new column.

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_divide_columns(
    self, column_a: str, column_b: str, new_column: str
) -> Self:
    """Divide column_a by column_b into a new column.

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_divide_columns,
        {"column_a": column_a, "column_b": column_b, "new_column": new_column},
    )

math_percent_of

math_percent_of(
    column: str, total_column: str, new_column: str, multiply_by: float = 100.0
) -> Self

Calculate percentage of one column relative to another.

Parameters:

Name Type Description Default
column str

Numerator column.

required
total_column str

Denominator column.

required
new_column str

Name for result column.

required
multiply_by float

Multiplier (default 100 for percentage).

100.0

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_percent_of(
    self,
    column: str,
    total_column: str,
    new_column: str,
    multiply_by: float = 100.0,
) -> Self:
    """Calculate percentage of one column relative to another.

    Args:
        column: Numerator column.
        total_column: Denominator column.
        new_column: Name for result column.
        multiply_by: Multiplier (default 100 for percentage).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_percent_of,
        {
            "column": column,
            "total_column": total_column,
            "new_column": new_column,
            "multiply_by": multiply_by,
        },
    )

math_cumsum

math_cumsum(
    column: str,
    new_column: str | None = None,
    group_by: str | list[str] | None = None,
) -> Self

Calculate cumulative sum.

Parameters:

Name Type Description Default
column str

Column to sum.

required
new_column str | None

Name for result column (None = modify in place).

None
group_by str | list[str] | None

Optional column(s) to group by.

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_cumsum(
    self,
    column: str,
    new_column: str | None = None,
    group_by: str | list[str] | None = None,
) -> Self:
    """Calculate cumulative sum.

    Args:
        column: Column to sum.
        new_column: Name for result column (None = modify in place).
        group_by: Optional column(s) to group by.

    Returns:
        Self for method chaining.
    """
    if isinstance(group_by, str):
        group_by = [group_by]
    return self._register(
        self._math_cumsum,
        {
            "column": column,
            "new_column": new_column or column,
            "group_by": group_by,
        },
    )

math_rank

math_rank(
    column: str,
    new_column: str,
    method: RankMethod = "ordinal",
    *,
    descending: bool = False,
    group_by: str | list[str] | None = None,
) -> Self

Calculate rank of values.

Parameters:

Name Type Description Default
column str

Column to rank.

required
new_column str

Name for result column.

required
method RankMethod

Ranking method ('ordinal', 'dense', 'min', 'max', 'average').

'ordinal'
descending bool

Rank in descending order.

False
group_by str | list[str] | None

Optional column(s) to group by.

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_rank(
    self,
    column: str,
    new_column: str,
    method: RankMethod = "ordinal",
    *,
    descending: bool = False,
    group_by: str | list[str] | None = None,
) -> Self:
    """Calculate rank of values.

    Args:
        column: Column to rank.
        new_column: Name for result column.
        method: Ranking method ('ordinal', 'dense', 'min', 'max', 'average').
        descending: Rank in descending order.
        group_by: Optional column(s) to group by.

    Returns:
        Self for method chaining.
    """
    if isinstance(group_by, str):
        group_by = [group_by]
    return self._register(
        self._math_rank,
        {
            "column": column,
            "new_column": new_column,
            "method": method,
            "descending": descending,
            "group_by": group_by,
        },
    )

math_standardize

math_standardize(
    column: str,
    *,
    mean: Numeric | None = None,
    std: Numeric | None = None,
    new_column: str | None = None,
) -> Self

Standardize a column to have mean=0 and std=1 (z-score).

Parameters:

Name Type Description Default
column str

Column to transform.

required
mean Numeric | None

Mean value. If None, derived from data.

None
std Numeric | None

Standard deviation. If None, derived from data.

None
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_standardize(
    self,
    column: str,
    *,
    mean: Numeric | None = None,
    std: Numeric | None = None,
    new_column: str | None = None,
) -> Self:
    """Standardize a column to have mean=0 and std=1 (z-score).

    Args:
        column: Column to transform.
        mean: Mean value. If None, derived from data.
        std: Standard deviation. If None, derived from data.
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_standardize,
        {
            "column": column,
            "mean": mean,
            "std": std,
            "new_column": new_column or column,
        },
    )

math_minmax

math_minmax(
    column: str,
    *,
    min_val: Numeric | None = None,
    max_val: Numeric | None = None,
    feature_range: FeatureRange = (0, 1),
    new_column: str | None = None,
) -> Self

Scale a column to a range using min-max normalization.

Parameters:

Name Type Description Default
column str

Column to transform.

required
min_val Numeric | None

Minimum value. If None, derived from data.

None
max_val Numeric | None

Maximum value. If None, derived from data.

None
feature_range FeatureRange

Output range tuple (default: (0, 1)).

(0, 1)
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_minmax(
    self,
    column: str,
    *,
    min_val: Numeric | None = None,
    max_val: Numeric | None = None,
    feature_range: FeatureRange = (0, 1),
    new_column: str | None = None,
) -> Self:
    """Scale a column to a range using min-max normalization.

    Args:
        column: Column to transform.
        min_val: Minimum value. If None, derived from data.
        max_val: Maximum value. If None, derived from data.
        feature_range: Output range tuple (default: (0, 1)).
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_minmax,
        {
            "column": column,
            "min_val": min_val,
            "max_val": max_val,
            "feature_range": feature_range,
            "new_column": new_column or column,
        },
    )

math_robust_scale

math_robust_scale(
    column: str,
    *,
    median: Numeric | None = None,
    iqr: Numeric | None = None,
    new_column: str | None = None,
) -> Self

Scale a column using median and interquartile range.

Robust to outliers compared to standardization.

Parameters:

Name Type Description Default
column str

Column to transform.

required
median Numeric | None

Median value. If None, derived from data.

None
iqr Numeric | None

Interquartile range (Q3 - Q1). If None, derived from data.

None
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_robust_scale(
    self,
    column: str,
    *,
    median: Numeric | None = None,
    iqr: Numeric | None = None,
    new_column: str | None = None,
) -> Self:
    """Scale a column using median and interquartile range.

    Robust to outliers compared to standardization.

    Args:
        column: Column to transform.
        median: Median value. If None, derived from data.
        iqr: Interquartile range (Q3 - Q1). If None, derived from data.
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_robust_scale,
        {
            "column": column,
            "median": median,
            "iqr": iqr,
            "new_column": new_column or column,
        },
    )

math_log

math_log(
    column: str,
    *,
    base: Numeric | None = None,
    offset: Numeric = 0,
    new_column: str | None = None,
) -> Self

Apply logarithmic transform to a column.

Parameters:

Name Type Description Default
column str

Column to transform.

required
base Numeric | None

Log base (default: natural log e).

None
offset Numeric

Value added before log to handle zeros (default: 0).

0
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_log(
    self,
    column: str,
    *,
    base: Numeric | None = None,
    offset: Numeric = 0,
    new_column: str | None = None,
) -> Self:
    """Apply logarithmic transform to a column.

    Args:
        column: Column to transform.
        base: Log base (default: natural log e).
        offset: Value added before log to handle zeros (default: 0).
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_log,
        {
            "column": column,
            "base": base,
            "offset": offset,
            "new_column": new_column or column,
        },
    )

math_sqrt

math_sqrt(column: str, *, new_column: str | None = None) -> Self

Apply square root transform to a column.

Parameters:

Name Type Description Default
column str

Column to transform.

required
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_sqrt(
    self,
    column: str,
    *,
    new_column: str | None = None,
) -> Self:
    """Apply square root transform to a column.

    Args:
        column: Column to transform.
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_sqrt,
        {
            "column": column,
            "new_column": new_column or column,
        },
    )

math_power

math_power(
    column: str, exponent: Numeric, *, new_column: str | None = None
) -> Self

Apply power transform to a column.

Parameters:

Name Type Description Default
column str

Column to transform.

required
exponent Numeric

Power to raise values to.

required
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_power(
    self,
    column: str,
    exponent: Numeric,
    *,
    new_column: str | None = None,
) -> Self:
    """Apply power transform to a column.

    Args:
        column: Column to transform.
        exponent: Power to raise values to.
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_power,
        {
            "column": column,
            "exponent": exponent,
            "new_column": new_column or column,
        },
    )

math_winsorize

math_winsorize(
    column: str,
    *,
    lower: Numeric | None = None,
    upper: Numeric | None = None,
    lower_value: Numeric | None = None,
    upper_value: Numeric | None = None,
    new_column: str | None = None,
) -> Self

Clip values to percentiles or explicit bounds.

Use either percentile-based (lower/upper as 0-1 fractions) or value-based (lower_value/upper_value as explicit bounds) clipping.

Parameters:

Name Type Description Default
column str

Column to transform.

required
lower Numeric | None

Lower percentile (0-1). E.g., 0.05 for 5th percentile.

None
upper Numeric | None

Upper percentile (0-1). E.g., 0.95 for 95th percentile.

None
lower_value Numeric | None

Explicit lower bound (overrides lower percentile).

None
upper_value Numeric | None

Explicit upper bound (overrides upper percentile).

None
new_column str | None

Output column name (default: replace original).

None

Returns:

Type Description
Self

Self for method chaining.

Source code in transformplan/ops/math.py
def math_winsorize(
    self,
    column: str,
    *,
    lower: Numeric | None = None,
    upper: Numeric | None = None,
    lower_value: Numeric | None = None,
    upper_value: Numeric | None = None,
    new_column: str | None = None,
) -> Self:
    """Clip values to percentiles or explicit bounds.

    Use either percentile-based (lower/upper as 0-1 fractions) or
    value-based (lower_value/upper_value as explicit bounds) clipping.

    Args:
        column: Column to transform.
        lower: Lower percentile (0-1). E.g., 0.05 for 5th percentile.
        upper: Upper percentile (0-1). E.g., 0.95 for 95th percentile.
        lower_value: Explicit lower bound (overrides lower percentile).
        upper_value: Explicit upper bound (overrides upper percentile).
        new_column: Output column name (default: replace original).

    Returns:
        Self for method chaining.
    """
    return self._register(
        self._math_winsorize,
        {
            "column": column,
            "lower": lower,
            "upper": upper,
            "lower_value": lower_value,
            "upper_value": upper_value,
            "new_column": new_column or column,
        },
    )

Examples

Scalar Operations

# Add to every value
plan = TransformPlan().math_add("price", 10)

# Subtract from every value
plan = TransformPlan().math_subtract("score", 5)

# Multiply every value
plan = TransformPlan().math_multiply("quantity", 1.5)

# Divide every value
plan = TransformPlan().math_divide("total", 100)

Column-wise Operations

# Add two columns into a new column
plan = TransformPlan().math_add_columns("base", "bonus", "total")

# Subtract columns
plan = TransformPlan().math_subtract_columns("revenue", "cost", "profit")

# Multiply columns
plan = TransformPlan().math_multiply_columns("price", "quantity", "total")

# Divide columns
plan = TransformPlan().math_divide_columns("score", "max_score", "percentage")

Value Clamping

# Clamp to range
plan = TransformPlan().math_clamp("score", lower=0, upper=100)

# Set minimum value
plan = TransformPlan().math_set_min("quantity", min_value=0)

# Set maximum value
plan = TransformPlan().math_set_max("discount", max_value=50)

Transformations

# Absolute value
plan = TransformPlan().math_abs("difference")

# Round to decimal places
plan = TransformPlan().math_round("price", decimals=2)

Percentage Calculation

# Calculate percentage
plan = TransformPlan().math_percent_of(
    column="part",
    total_column="whole",
    new_column="percentage",
    multiply_by=100  # default
)

Cumulative and Ranking Operations

# Cumulative sum
plan = TransformPlan().math_cumsum(
    column="sales",
    new_column="running_total",
    group_by="region"
)

# Rank values
plan = TransformPlan().math_rank(
    column="score",
    new_column="rank",
    method="dense",
    descending=True,
    group_by="category"
)

Scaling Operations

# Z-score standardization (explicit params for reproducibility)
plan = TransformPlan().math_standardize("income", mean=50000, std=25000)

# Derive from data
plan = TransformPlan().math_standardize("income")

# Min-max normalization to [0, 1]
plan = TransformPlan().math_minmax("age", min_val=0, max_val=100)

# Custom range
plan = TransformPlan().math_minmax("score", min_val=0, max_val=100, feature_range=(0, 10))

# Robust scaling (resistant to outliers)
plan = TransformPlan().math_robust_scale("salary", median=60000, iqr=30000)

Transform Operations

# Natural log
plan = TransformPlan().math_log("price")

# Log base 10
plan = TransformPlan().math_log("price", base=10)

# Log with offset for zeros
plan = TransformPlan().math_log("count", offset=1)  # log(x + 1)

# Square root
plan = TransformPlan().math_sqrt("variance")

# Power transform
plan = TransformPlan().math_power("value", exponent=2)  # square
plan = TransformPlan().math_power("value", exponent=0.5)  # sqrt

Outlier Handling

# Winsorize by percentiles
plan = TransformPlan().math_winsorize("salary", lower=0.05, upper=0.95)

# Winsorize by explicit values
plan = TransformPlan().math_winsorize("salary", lower_value=20000, upper_value=200000)