Skip to content

Python Pandas - Window Functions

Pandas provides powerful tools for performing calculations over sliding or expanding windows of data. These are essential for tasks like calculating moving averages, cumulative sums, or time series analysis where trends and patterns over specific periods are important.

The main types of window operations are:

  • Rolling Windows: Compute statistics over a fixed-size sliding window.
  • Expanding Windows: Compute statistics cumulatively, including all data points from the start up to the current point.
  • Exponentially Weighted Moving (EWM) Windows: Similar to rolling windows, but assign greater weight to more recent observations.

These operations are typically accessed via methods like .rolling(), .expanding(), and .ewm() applied to Series or DataFrame objects, followed by an aggregation function (e.g., .mean(), .sum(), .std(), .max()).

Let’s create a sample time series DataFrame:

import pandas as pd
import numpy as np
# Create DataFrame with a DatetimeIndex
dates = pd.date_range('20230101', periods=10)
df = pd.DataFrame(np.random.randn(10, 4), index=dates, columns=list('ABCD'))
print("Sample DataFrame:")
print(df)

(Output will vary due to random numbers)

The .rolling() method defines a window of a specified size that slides along the data. You must provide the window size (number of observations).

# Calculate the 3-period rolling mean
print("\n3-Period Rolling Mean:")
print(df.rolling(window=3).mean())

Output (example):

3-Period Rolling Mean:
A B C D
2023-01-01 NaN NaN NaN NaN
2023-01-02 NaN NaN NaN NaN
2023-01-03 0.434553 -0.667940 -1.051718 -0.826452
2023-01-04 0.628267 -0.047040 -0.287467 -0.161110
2023-01-05 0.398233 0.003517 0.099126 -0.405565
2023-01-06 0.641798 0.656184 -0.322728 0.428015
2023-01-07 0.188403 0.010913 -0.708645 0.160932
2023-01-08 0.188043 -0.253039 -0.818125 -0.108485
2023-01-09 0.682819 -0.606846 -0.178411 -0.404127
2023-01-10 0.688583 0.127786 0.513832 -1.067156

Explanation: Notice the NaN values for the first two rows. This is because a complete window of size 3 is not available until the third data point. The value for ‘2023-01-03’ is the mean of the values from ‘2023-01-01’, ‘2023-01-02’, and ‘2023-01-03’. The window then slides one step forward for the next calculation.

You can apply other aggregations like .sum(), .std(), .max(), etc., after .rolling().

# Calculate the 3-period rolling sum
print("\n3-Period Rolling Sum:")
print(df.rolling(window=3).sum())

.rolling() also supports time-based windows (e.g., df.rolling('3D').sum()) if the index is time-based, and options like center=True to center the window label.

The .expanding() method creates a window that grows cumulatively. The calculation at each point includes all data from the beginning up to that point. You usually specify min_periods to determine the minimum number of observations required to produce a value.

# Calculate the expanding mean (requires at least 3 periods)
print("\nExpanding Mean (min_periods=3):")
print(df.expanding(min_periods=3).mean())

Output (example):

Expanding Mean (min_periods=3):
A B C D
2023-01-01 NaN NaN NaN NaN
2023-01-02 NaN NaN NaN NaN
2023-01-03 0.434553 -0.667940 -1.051718 -0.826452
2023-01-04 0.743328 -0.198015 -0.852462 -0.262547
2023-01-05 0.614776 -0.205649 -0.583641 -0.303254
2023-01-06 0.538175 -0.005878 -0.687223 -0.199219
2023-01-07 0.505503 -0.108475 -0.790826 -0.081056
2023-01-08 0.454751 -0.223420 -0.671572 -0.230215
2023-01-09 0.586390 -0.206201 -0.517619 -0.267521
2023-01-10 0.560427 -0.037597 -0.399429 -0.376886

Explanation: Similar to rolling, the first two rows are NaN due to min_periods=3. The value for ‘2023-01-03’ is the mean of the first three rows. The value for ‘2023-01-04’ is the mean of the first four rows, and so on. It’s useful for calculating cumulative statistics like running totals or averages.

# Calculate the expanding sum (cumulative sum)
print("\nExpanding Sum (min_periods=1):")
print(df.expanding(min_periods=1).sum()) # Equivalent to df.cumsum()

.ewm() Function (Exponentially Weighted Moving)

Section titled “.ewm() Function (Exponentially Weighted Moving)”

Exponentially Weighted Moving (EWM) functions assign weights to observations, giving more importance to recent data points. The weights decrease exponentially as observations get older. Instead of a fixed window size, the decay is controlled by parameters like:

  • span: Specifies the window size in terms of a period (common for smoothing).
  • com (center of mass): Alternative way to specify decay.
  • halflife: The period over which the weight decays by half.
  • alpha: Directly specify the smoothing factor (0 < alpha <= 1).

You only need to specify one of these decay parameters.

# Calculate the exponentially weighted moving average with a span of 3
print("\nEWM Mean (span=3):")
print(df.ewm(span=3).mean())

Output (example):

EWM Mean (span=3):
A B C D
2023-01-01 1.088512 -0.650942 -2.547450 -0.566858
2023-01-02 0.584818 -0.918843 -1.502458 -1.009155
2023-01-03 0.160516 -0.852000 -0.862254 -1.266023
2023-01-04 0.806731 -0.000790 -0.527406 -0.317778
2023-01-05 0.550059 -0.027708 -0.227423 -0.357230
2023-01-06 0.659042 0.449324 -0.440189 0.198016
2023-01-07 0.277761 0.064759 -0.751578 0.220442
2023-01-08 0.221687 -0.282486 -0.685453 -0.090833
2023-01-09 0.909541 -0.263199 -0.222084 -0.229127
2023-01-10 0.740476 0.240152 0.163507 -0.686182

EWM functions are commonly used for smoothing time series data to highlight underlying trends by reducing noise, especially in financial data analysis.

Window functions are widely applied in various domains:

  • Time Series Analysis: Calculating moving averages/standard deviations to identify trends and volatility.
  • Finance: Computing stock return volatility, moving average convergence divergence (MACD).
  • Signal Processing: Smoothing noisy signals.
  • Data Cleaning: Identifying outliers based on rolling statistics.
  • Feature Engineering: Creating features for machine learning models based on recent trends (e.g., average sales in the last 7 days).

By applying window computations and visualizing the results, you can often reveal patterns and trends that are not immediately obvious in the raw data.