Data Analysis with pandas · Analysis with pandas

Time Series: Dates, Resampling and Rolling Windows

Work with datetime columns, resample events into daily or weekly totals, fill missing days, and compute rolling averages and changes.

Create a free account to save this page, take notes and track your progress. Sign in

What you'll build

Daily and weekly revenue from individual orders, with days that had no orders filled in as zero, a 3-day rolling average to smooth noise, and day-over-day change: the core of any metrics chart.

The idea

  • Use a DatetimeIndex (set_index("date")) for time-based operations.
  • resample("D"), "W", "MS" groups by calendar periods; empty periods appear (fill them with asfreq/fillna(0)).
  • rolling(window) computes moving statistics; pct_change() and diff() compute changes.
  • .dt gives date parts; tz_localize/tz_convert handle time zones.

The code

Daily revenue, rolling average and weekly totalsTry it yourself
from io import StringIO
import pandas as pd

csv = StringIO("""order_id,date,customer,country,product,quantity,unit_price
1001,2026-01-03,ana,DE,mug,2,8.50
1002,2026-01-03,ben,US,teapot,1,24.00
1003,2026-01-04,chen,DE,kettle,1,31.90
1004,2026-01-05,ana,DE,teapot,1,24.00
1005,2026-01-07,dara,FR,mug,4,8.50
1006,2026-01-07,ben,US,mug,1,8.50
""")
orders = pd.read_csv(csv, parse_dates=["date"])

orders["total"] = orders["quantity"] * orders["unit_price"]
daily = orders.set_index("date")["total"].resample("D").sum()      # days without orders become 0
report = pd.DataFrame({
    "revenue": daily,
    "rolling_3d": daily.rolling(3, min_periods=1).mean().round(2),
    "change": daily.diff(),
})
print(report)
weekly = daily.resample("W-SUN").sum()
print(weekly)
print("best day:", daily.idxmax().date(), daily.max())

Output

            revenue  rolling_3d  change
date                                   
2026-01-03     41.0       41.00     NaN
2026-01-04     31.9       36.45    -9.1
2026-01-05     24.0       32.30    -7.9
2026-01-06      0.0       18.63   -24.0
2026-01-07     42.5       22.17    42.5
date
2026-01-04    72.9
2026-01-11    66.5
Freq: W-SUN, Name: total, dtype: float64
best day: 2026-01-07 42.5

Common mistakes

  • Treating dates as strings: sorting and resampling don't work; parse them with parse_dates/to_datetime.
  • Charting only days with data, hiding gaps; resample to a regular frequency first.
  • Mixing time zones; store UTC and convert for display.
  • Rolling windows without min_periods, producing NaN at the start.

Key points

  • Put datetimes in the index for resampling and rolling.
  • resample creates regular periods, including empty ones.
  • rolling, diff and pct_change describe trends.

Further reading: Time series / date functionality · Windowing operations

Practice questions

What does resample('D').sum() do with days that have no data?

Answer

It creates those days with a sum of 0 (or NaN for other aggregations), giving a regular daily series.

What does rolling(3).mean() compute?

Answer

The average of each value and the two before it (a 3-period moving average); min_periods controls the start.

How should time zones be handled?

Answer

Store timestamps in UTC (tz-aware), convert to local time zones only for display with tz_convert.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?