Pandas Window Series

A single-column proxy on a window frame.

A WindowSeries is obtained by bracket-indexing a PandasApiWindowTdsFrame with a column name. It can also be obtained by calling expanding(), rolling(), or window_frame_legend_ext() directly on a Series or GroupbySeries.

Calling an aggregation method (sum(), mean(), etc.) on a WindowSeries returns a Series (or a GroupbySeries when the underlying window was created from a groupby). Positional window functions (first(), last(), shift()) and the general-purpose window_extend_legend_ext() are also available. The result can then be assigned back to the parent frame.

Obtaining a WindowSeries

# Via bracket notation on a window frame
ws = frame.expanding(order_by="col")["col"]

# Via Series shortcut
ws = frame["col"].expanding(order_by="col")

# Grouped variant (returns GroupbySeries after aggregation)
ws = frame.groupby("grp")["val"].expanding(order_by="val")

Result type preservation

The type of the returned Series (or GroupbySeries) matches the column type. For example, an integer column produces an IntegerSeries after .sum(), while count() always returns an IntegerSeries regardless of the source column type.

Composing with arithmetic

The Series returned by a WindowSeries aggregation supports arithmetic, so expressions like the following work:

frame["shifted"] = frame["col"].expanding().sum() - 100
frame["ratio"]   = frame["a"].expanding().sum() / frame["b"]

Multiple window assignments can be applied sequentially to the same frame:

frame["cumsum"]    = frame["col"].expanding().sum()
frame["roll_mean"] = frame["col2"].rolling(5, order_by="col2").mean()

See also

PandasApiWindowTdsFrame

The window frame that produces this.

Series

Non-grouped single-column proxy.

GroupbySeries

Grouped single-column proxy.

PandasApiTdsFrame.expanding

Create an expanding window on a frame.

PandasApiTdsFrame.rolling

Create a rolling window on a frame.

Notes

Differences from pandas:

  • A WindowSeries is not a data container. It is an expression builder that lazily constructs the SQL / Pure query. No data is materialised until the result is executed.

  • In pandas, Expanding['col'] and Rolling['col'] have built-in convenience methods that return a Series. Here, the same convenience methods are available (sum(), mean(), min(), max(), count(), std(), var()), plus positional window methods (first(), last(), shift()), and a general aggregate() / agg() method. window_extend_legend_ext() is available for fully custom window expressions.

  • Extra *args / **kwargs on aggregate() are not supported.

  • The numeric_only parameter on convenience methods is not supported and must be False.

Examples

Download Interactive Notebook

agg

WindowSeries.agg(func, axis=0, *args, **kwargs)[source]

Apply a window aggregate to this single column.

Alias for aggregate(). See aggregate for full documentation.

See also

aggregate

Equivalent method (canonical name).

Return type:

Union[Series, GroupbySeries]

aggregate

WindowSeries.aggregate(func, axis=0, *args, **kwargs)[source]

Apply a window aggregate to this single column.

Compute the window aggregate specified by func over the window defined on this WindowSeries. The result is a Series (or GroupbySeries when the underlying window was created from a groupby) that can be assigned back to a frame column.

Parameters:
  • func (Union[Callable[..., Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]], str, ufunc, List[Union[Callable[..., Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]], str, ufunc]], Mapping[Hashable, Union[Callable[..., Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]], str, ufunc, List[Union[Callable[..., Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]], str, ufunc]]]]]) –

    Aggregation specification:

    • str — a named aggregation ('sum', 'mean', 'min', 'max', 'count', 'std', 'var').

    • callable — a function receiving a column proxy and returning an aggregated value.

    • list — a list of the above.

    • dict{column_name: agg_spec}.

  • axis (Union[int, str]) – Only 0 / 'index' is supported.

  • *args (Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]) – Not supported.

  • **kwargs (Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]) – Not supported.

Returns:

A single-column proxy containing the windowed aggregate values.

Return type:

Union[Series, GroupbySeries]

See also

agg

Alias for aggregate.

sum

Windowed sum convenience method.

mean

Windowed mean convenience method.

PandasApiWindowTdsFrame.aggregate

Window aggregate on all columns.

Notes

Differences from pandas:

  • In pandas, Expanding['col'].aggregate() and Rolling['col'].aggregate() accept *args and **kwargs forwarded to the aggregation function. Here, extra positional and keyword arguments are not supported.

  • The result is always a single-column proxy (Series or GroupbySeries), never a DataFrame.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Expanding sum on a single column
frame["Expanding Sum"] = frame.expanding(
    order_by="Order Id"
)["Order Id"].aggregate("sum")
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Expanding Sum
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 20497
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 30747
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 40998
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 51250

count

WindowSeries.count()[source]

Compute the windowed count of non-null values for this column.

Convenience method equivalent to aggregate('count') on this window series.

Returns:

A single-column proxy containing the windowed count values. The return type is always IntegerSeries (or its GroupbySeries equivalent), regardless of the source column’s type.

Return type:

Union[Series, GroupbySeries]

See also

aggregate

General windowed aggregation.

sum

Windowed sum.

PandasApiTdsFrame.count

Frame-level count (no window).

Notes

Differences from pandas:

  • The signature takes no parameters. The pandas Expanding.count() / Rolling.count() accept numeric_only which is not supported here.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Expanding count on a single column
frame["Expanding Count"] = frame.expanding(
    order_by="Order Id"
)["Order Id"].count()
frame.head(5).to_pandas()

first

WindowSeries.first()[source]

Return the first value in the window for this column.

Generates first_value(col) OVER (...) in SQL.

Returns:

A single-column proxy containing the first value within the window for every row.

Return type:

Union[Series, GroupbySeries]

See also

last

Last value in the window.

PandasApiWindowTdsFrame.first

All-column version.

shift

Lag/lead by N rows.

Notes

Differences from pandas:

  • first() is a pylegend extension. There is no Expanding['col'].first() or Rolling['col'].first() in pandas.

  • Internally delegates to window_extend_legend_ext with value_func = lambda p, w, r: p.first(w, r)["col"].

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
frame["First Order"] = frame.window_frame_legend_ext(
    frame_spec=frame.rows_between(),
    order_by="Order Id",
)["Order Id"].first()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name First Order
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10248
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10248
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10248
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10248

last

WindowSeries.last()[source]

Return the last value in the window for this column.

Generates last_value(col) OVER (...) in SQL.

Returns:

A single-column proxy containing the last value within the window for every row.

Return type:

Union[Series, GroupbySeries]

See also

first

First value in the window.

PandasApiWindowTdsFrame.last

All-column version.

shift

Lag/lead by N rows.

Notes

Differences from pandas:

  • last() is a pylegend extension. There is no Expanding['col'].last() or Rolling['col'].last() in pandas.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
frame["Last Order"] = frame.window_frame_legend_ext(
    frame_spec=frame.rows_between(),
    order_by="Order Id",
)["Order Id"].last()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Last Order
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 11077
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 11077
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 11077
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 11077
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 11077

max

WindowSeries.max(numeric_only=False)[source]

Compute the windowed maximum of this column.

Convenience method equivalent to aggregate('max') on this window series.

Parameters:

numeric_only (bool) – Must be False. True is not supported.

Returns:

A single-column proxy containing the windowed maximum values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If numeric_only is True.

See also

aggregate

General windowed aggregation.

min

Windowed minimum.

PandasApiTdsFrame.max

Frame-level max (no window).

Notes

Differences from pandas:

  • numeric_only is not supported and must be False.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Expanding max on a single column
frame["Expanding Max"] = frame.expanding(
    order_by="Order Id"
)["Order Id"].max()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Expanding Max
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10249
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10250
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10251
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10252

mean

WindowSeries.mean(numeric_only=False)[source]

Compute the windowed mean of this column.

Convenience method equivalent to aggregate('mean') on this window series.

Parameters:

numeric_only (bool) – Must be False. True is not supported.

Returns:

A single-column proxy containing the windowed mean values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If numeric_only is True.

See also

aggregate

General windowed aggregation.

sum

Windowed sum.

PandasApiTdsFrame.mean

Frame-level mean (no window).

Notes

Differences from pandas:

  • numeric_only is not supported and must be False.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Rolling mean with a window of 3
frame["Rolling Mean"] = frame.rolling(
    3, order_by="Order Id"
)["Order Id"].mean()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Rolling Mean
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248.0
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10248.5
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10249.0
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10250.0
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10251.0

min

WindowSeries.min(numeric_only=False)[source]

Compute the windowed minimum of this column.

Convenience method equivalent to aggregate('min') on this window series.

Parameters:

numeric_only (bool) – Must be False. True is not supported.

Returns:

A single-column proxy containing the windowed minimum values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If numeric_only is True.

See also

aggregate

General windowed aggregation.

max

Windowed maximum.

PandasApiTdsFrame.min

Frame-level min (no window).

Notes

Differences from pandas:

  • numeric_only is not supported and must be False.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Expanding min on a single column
frame["Expanding Min"] = frame.expanding(
    order_by="Order Id"
)["Order Id"].min()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Expanding Min
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10248
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10248
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10248
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10248

shift

WindowSeries.shift(periods=1, freq=None, axis=0, fill_value=None, suffix=None)[source]

Shift (lag or lead) this column by N rows within the window.

Generates lag(col, N) for positive periods and lead(col, N) for non-positive periods in SQL.

Because lag/lead SQL functions do not accept a frame clause, shift() automatically strips the frame_spec when it is the default RowsBetween(None, None) or None. If a non-default frame spec (e.g. rows_between(-2, 2)) is set, a ValueError is raised.

Parameters:
  • periods (int) –

    Number of rows to shift.

    • periods = 1 - lag (look backward).

    • periods = -1 - lead (look forward), with offset abs(periods).

    • periods = 0lead(col, 0) (current row).

  • freq (Optional[str]) – Not supported. Raises NotImplementedError.

  • axis (int) – Only 0 / 'index' is supported.

  • fill_value (Optional[object]) – Not supported. Raises NotImplementedError.

  • suffix (Optional[str]) – Not supported. Raises NotImplementedError.

Returns:

A single-column proxy containing the shifted values.

Return type:

Union[Series, GroupbySeries]

Raises:
  • NotImplementedError – If freq, fill_value, suffix is not None, axis is not 0, or periods is not an int.

  • ValueError – If the window has a non-default frame_spec (only RowsBetween(None, None) or None are permitted).

See also

first

First value in the window.

last

Last value in the window.

Notes

Differences from pandas:

  • In pandas, Series.shift() accepts freq, fill_value, and suffix, none of which are supported here.

  • shift() does not mutate the original window frame. Internally it creates a shallow copy with frame_spec=None so that the generated SQL omits the ROWS BETWEEN / RANGE BETWEEN clause.

Edge cases:

  • shift(periods=0) generates lead(col, 0), which returns the current row’s value (identity operation).

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Previous row's Order Id (lag by 1)
frame["Prev Order"] = frame.window_frame_legend_ext(
    order_by="Order Id",
)["Order Id"].shift(periods=1)
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Prev Order
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier <NA>
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10248
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10249
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10250
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10251
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Next row's Order Id (lead by 1)
frame["Next Order"] = frame.window_frame_legend_ext(
    order_by="Order Id",
)["Order Id"].shift(periods=-1)
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Next Order
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10249
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10250
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10251
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10252
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10253

std

WindowSeries.std(ddof=1, numeric_only=False)[source]

Compute the windowed standard deviation of this column.

Convenience method equivalent to aggregate('std') on this window series.

Parameters:
  • ddof (int) – Degrees of freedom. 1 for sample standard deviation (STDDEV_SAMP), 0 for population standard deviation (STDDEV_POP).

  • numeric_only (bool) – Must be False. True is not supported.

Returns:

A single-column proxy containing the windowed standard deviation values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If ddof is not 0 or 1, or if numeric_only is True.

See also

aggregate

General windowed aggregation.

var

Windowed variance.

PandasApiTdsFrame.std

Frame-level std (no window).

Notes

Differences from pandas:

  • Only ddof=0 (population) and ddof=1 (sample) are supported. Other values raise NotImplementedError.

  • numeric_only is not supported and must be False.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Rolling standard deviation with a window of 3
frame["Rolling Std"] = frame.rolling(
    3, order_by="Order Id"
)["Order Id"].std()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Rolling Std
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier <NA>
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 0.707107
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 1.0
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 1.0
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 1.0

sum

WindowSeries.sum(numeric_only=False, min_count=0)[source]

Compute the windowed sum of this column.

Convenience method equivalent to aggregate('sum') on this window series.

Parameters:
  • numeric_only (bool) – Must be False. True is not supported.

  • min_count (int) – Must be 0. Non-zero values are not supported.

Returns:

A single-column proxy containing the windowed sum values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If any parameter is set to an unsupported value.

See also

aggregate

General windowed aggregation.

mean

Windowed mean.

PandasApiTdsFrame.sum

Frame-level sum (no window).

Notes

Differences from pandas:

  • numeric_only and min_count are not supported and must remain at their default values.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Expanding sum on a single column
frame["Expanding Sum"] = frame.expanding(
    order_by="Order Id"
)["Order Id"].sum()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Expanding Sum
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10248
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 20497
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 30747
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 40998
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 51250

var

WindowSeries.var(ddof=1, numeric_only=False)[source]

Compute the windowed variance of this column.

Convenience method equivalent to aggregate('var') on this window series.

Parameters:
  • ddof (int) – Degrees of freedom. 1 for sample variance (VAR_SAMP), 0 for population variance (VAR_POP).

  • numeric_only (bool) – Must be False. True is not supported.

Returns:

A single-column proxy containing the windowed variance values.

Return type:

Union[Series, GroupbySeries]

Raises:

NotImplementedError – If ddof is not 0 or 1, or if numeric_only is True.

See also

aggregate

General windowed aggregation.

std

Windowed standard deviation.

PandasApiTdsFrame.var

Frame-level var (no window).

Notes

Differences from pandas:

  • Only ddof=0 (population) and ddof=1 (sample) are supported. Other values raise NotImplementedError.

  • numeric_only is not supported and must be False.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# Rolling variance with a window of 3
frame["Rolling Var"] = frame.rolling(
    3, order_by="Order Id"
)["Order Id"].var()
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Rolling Var
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier <NA>
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 0.5
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 1.0
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 1.0
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 1.0

window_extend_legend_ext

WindowSeries.window_extend_legend_ext(value_func, agg_func=None)[source]

Apply a custom window function to this single column.

PyLegend extension — not present in pandas.

Compute a user-defined window expression for the selected column. The value_func receives three arguments — a PandasApiPartialFrame (p), a PandasApiWindowReference (w), and a PandasApiTdsRow (r) — and must return a single primitive. The result is a Series (or GroupbySeries) that can be assigned back to the parent frame.

Parameters:
  • value_func (Callable[[PandasApiPartialFrame, PyLegendWindowReference, PandasApiTdsRow], Union[int, float, str, bool, date, datetime, Decimal, PyLegendPrimitive]]) –

    (p, w, r) -> primitive.

    Common patterns:

    • lambda p, w, r: p.first(w, r)["col"] — first value.

    • lambda p, w, r: p.last(w, r)["col"] — last value.

    • lambda p, w, r: p.nth(w, r, 3)["col"] — nth value.

    • lambda p, w, r: p.lag(r, 1)["col"] — lag.

    • lambda p, w, r: p.lead(r, 2)["col"] — lead.

    • lambda p, w, r: r["col"] — raw column ref (combined with agg_func).

  • agg_func (Optional[Callable[[PyLegendPrimitiveCollection], PyLegendPrimitive]]) – (collection) -> primitive. If provided, an additional aggregation step (e.g. lambda c: c.sum()) is applied on top of the value_func result.

Returns:

A single-column proxy containing the window function result.

Return type:

Union[Series, GroupbySeries]

See also

PandasApiWindowTdsFrame.window_extend_legend_ext

Same operation applied to all columns.

first

Convenience wrapper using p.first(w, r)["col"].

last

Convenience wrapper using p.last(w, r)["col"].

shift

Convenience wrapper for lag/lead.

Examples

Download Interactive Notebook

import pylegend
frame = pylegend.samples.pandas_api.northwind_orders_frame()
# nth-value of a single column
frame["Nth Order"] = frame.window_frame_legend_ext(
    frame_spec=frame.rows_between(),
    order_by="Order Id",
)["Order Id"].window_extend_legend_ext(
    value_func=lambda p, w, r: p.nth(w, r, 3)["Order Id"],
)
frame.head(5).to_pandas()
Order Id Order Date Required Date Shipped Date Ship Name Nth Order
0 10248 1996-07-04 1996-08-01 1996-07-16 Vins et alcools Chevalier 10250
1 10249 1996-07-05 1996-08-16 1996-07-10 Toms Spezialitäten 10250
2 10250 1996-07-08 1996-08-05 1996-07-12 Hanari Carnes 10250
3 10251 1996-07-08 1996-08-05 1996-07-15 Victuailles en stock 10250
4 10252 1996-07-09 1996-08-06 1996-07-11 Suprêmes délices 10250