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
PandasApiWindowTdsFrameThe window frame that produces this.
SeriesNon-grouped single-column proxy.
GroupbySeriesGrouped single-column proxy.
PandasApiTdsFrame.expandingCreate an expanding window on a frame.
PandasApiTdsFrame.rollingCreate a rolling window on a frame.
Notes
Differences from pandas:
A
WindowSeriesis 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']andRolling['col']have built-in convenience methods that return aSeries. Here, the same convenience methods are available (sum(),mean(),min(),max(),count(),std(),var()), plus positional window methods (first(),last(),shift()), and a generalaggregate()/agg()method.window_extend_legend_ext()is available for fully custom window expressions.Extra
*args/**kwargsonaggregate()are not supported.The
numeric_onlyparameter on convenience methods is not supported and must beFalse.
Examples
Download Interactive Notebook
agg
- WindowSeries.agg(func, axis=0, *args, **kwargs)[source]
Apply a window aggregate to this single column.
Alias for
aggregate(). Seeaggregatefor full documentation.See also
aggregateEquivalent 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
funcover the window defined on thisWindowSeries. The result is aSeries(orGroupbySerieswhen 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]) – Only0/'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
Notes
Differences from pandas:
In pandas,
Expanding['col'].aggregate()andRolling['col'].aggregate()accept*argsand**kwargsforwarded to the aggregation function. Here, extra positional and keyword arguments are not supported.The result is always a single-column proxy (
SeriesorGroupbySeries), never a DataFrame.
Examples
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 itsGroupbySeriesequivalent), regardless of the source column’s type.- Return type:
Union[Series,GroupbySeries]
See also
Notes
Differences from pandas:
The signature takes no parameters. The pandas
Expanding.count()/Rolling.count()acceptnumeric_onlywhich is not supported here.
Examples
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
Notes
Differences from pandas:
first()is a pylegend extension. There is noExpanding['col'].first()orRolling['col'].first()in pandas.Internally delegates to
window_extend_legend_extwithvalue_func = lambda p, w, r: p.first(w, r)["col"].
Examples
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
Notes
Differences from pandas:
last()is a pylegend extension. There is noExpanding['col'].last()orRolling['col'].last()in pandas.
Examples
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 beFalse.Trueis not supported.- Returns:
A single-column proxy containing the windowed maximum values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
numeric_onlyisTrue.
See also
Notes
Differences from pandas:
numeric_onlyis not supported and must beFalse.
Examples
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 beFalse.Trueis not supported.- Returns:
A single-column proxy containing the windowed mean values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
numeric_onlyisTrue.
See also
Notes
Differences from pandas:
numeric_onlyis not supported and must beFalse.
Examples
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 beFalse.Trueis not supported.- Returns:
A single-column proxy containing the windowed minimum values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
numeric_onlyisTrue.
See also
Notes
Differences from pandas:
numeric_onlyis not supported and must beFalse.
Examples
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 positiveperiodsandlead(col, N)for non-positiveperiodsin SQL.Because lag/lead SQL functions do not accept a frame clause,
shift()automatically strips theframe_specwhen it is the defaultRowsBetween(None, None)orNone. If a non-default frame spec (e.g.rows_between(-2, 2)) is set, aValueErroris raised.- Parameters:
periods (
int) –Number of rows to shift.
periods = 1-lag(look backward).periods = -1-lead(look forward), with offsetabs(periods).periods = 0→lead(col, 0)(current row).
freq (
Optional[str]) – Not supported. RaisesNotImplementedError.axis (
int) – Only0/'index'is supported.fill_value (
Optional[object]) – Not supported. RaisesNotImplementedError.suffix (
Optional[str]) – Not supported. RaisesNotImplementedError.
- Returns:
A single-column proxy containing the shifted values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
freq,fill_value,suffixis notNone,axisis not0, orperiodsis not anint.ValueError – If the window has a non-default
frame_spec(onlyRowsBetween(None, None)orNoneare permitted).
Notes
Differences from pandas:
In pandas,
Series.shift()acceptsfreq,fill_value, andsuffix, none of which are supported here.shift()does not mutate the original window frame. Internally it creates a shallow copy withframe_spec=Noneso that the generated SQL omits theROWS BETWEEN/RANGE BETWEENclause.
Edge cases:
shift(periods=0)generateslead(col, 0), which returns the current row’s value (identity operation).
Examples
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.1for sample standard deviation (STDDEV_SAMP),0for population standard deviation (STDDEV_POP).numeric_only (
bool) – Must beFalse.Trueis not supported.
- Returns:
A single-column proxy containing the windowed standard deviation values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
ddofis not0or1, or ifnumeric_onlyisTrue.
See also
Notes
Differences from pandas:
Only
ddof=0(population) andddof=1(sample) are supported. Other values raiseNotImplementedError.numeric_onlyis not supported and must beFalse.
Examples
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 beFalse.Trueis not supported.min_count (
int) – Must be0. 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
Notes
Differences from pandas:
numeric_onlyandmin_countare not supported and must remain at their default values.
Examples
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.1for sample variance (VAR_SAMP),0for population variance (VAR_POP).numeric_only (
bool) – Must beFalse.Trueis not supported.
- Returns:
A single-column proxy containing the windowed variance values.
- Return type:
Union[Series,GroupbySeries]- Raises:
NotImplementedError – If
ddofis not0or1, or ifnumeric_onlyisTrue.
See also
Notes
Differences from pandas:
Only
ddof=0(population) andddof=1(sample) are supported. Other values raiseNotImplementedError.numeric_onlyis not supported and must beFalse.
Examples
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_funcreceives three arguments — aPandasApiPartialFrame(p), aPandasApiWindowReference(w), and aPandasApiTdsRow(r) — and must return a single primitive. The result is aSeries(orGroupbySeries) 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 withagg_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 thevalue_funcresult.
- Returns:
A single-column proxy containing the window function result.
- Return type:
Union[Series,GroupbySeries]
See also
Examples
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