Data in time: frequency, gaps, calendar
Forecasting and time series · Lesson 2 / 22
A series is not a table with a date column
Tabular data tolerates any row order. A time series does not: the order is the content. That gives you a set of checks that ordinary data preparation does not include, and these are the checks whose absence breaks forecasts most quietly.
Frequency and alignment
First put the series on a regular grid: one row per period, no holes and no duplicates. The check takes a minute and finds a surprising amount: missing days, two values on one date after a reload, a time zone change, a daylight saving switch where a single day contains 23 or 25 hours.
Grid diagnostics (before any model) periods expected: Sum(calendar from min to max date) = 1095 rows in the data: 1081 duplicate dates: 3 missing dates: 17 of them consecutive: 2024-03-08 .. 2024-03-19 zero values: 142 last date: 2026-05-02 (lag of 3 days to today)
A gap and a zero are different things
A missing row means there was no data. A value of zero means there were no sales. Mixing them means either declaring zero demand where the export simply failed, or losing the real zeros. The rule is simple: first work out why the period is missing, and only then decide what to fill it with.
- The export failed. Filling with zero is not allowed here: the model will learn fictitious dips. Either restore the data or mark the period as missing.
- The store was closed. Zero is correct, but it has to carry a closed flag, otherwise the model concludes that demand dropped.
- The item was out of stock. Zero in sales, but not zero in demand. This is the most expensive case: the model learns on suppressed demand and understates the order, which makes the item run out again.
The calendar is half of your accuracy
For daily series the calendar explains more than any model: day of week, holiday effects, pre-holiday buying peaks, payday effects, long weekends, moving dates such as Easter, the week number within the month. If the calendar is not supplied explicitly, the model will try to infer it from the series, and it will infer it badly, because a given holiday occurred three times in the history.
Month comparison is a trap of its own. February is three days shorter than January, and the number of working days in a month swings by two or three. A substantial part of what people call monthly revenue seasonality is in reality a calendar artefact, and it disappears once you normalise by the number of working days.
Aggregation changes the problem
The same series behaves differently at different granularity. Daily sales are noisy, weekly ones are visibly smoother, monthly ones are almost flat. The temptation to aggregate up to the level where the error looks respectable is strong, but granularity is dictated by the decision, not by the report: if the order is placed daily, weekly accuracy will not save you. The reverse rule holds too. Do not split the series finer than the decision is made, otherwise you pay in noise for detail that nobody will use.
Cheat sheet
- Put the series on a regular grid and count the holes and the duplicates.
- A gap, a zero and a stockout are three different facts.
- Sales are not demand.
- Supply the calendar explicitly; normalise months by working days.
Take a real series of your own (sales, tickets, load) covering at least a year. Put it on a regular grid and attach the diagnostics: how many periods the calendar expects, how many rows exist, how many duplicates, how many missing dates and whether they are consecutive, how many zeros, and the lag of the last date to today. For each type of gap, explain the cause, what you did with it, and why.