Scientific programming in Modula-9 — first steps

↖ contents

7 — Timeseries

A column of numbers with timestamps is not yet a timeseries. Three facts are usually lost between the instrument and the analysis: the RESOLUTION (is this half-hourly data, or irregular samples?), the CONVENTION (does 01:00 label the period that starts then, ends then, or is centred on it?), and the ZONE. Frame makes all three part of the data. A Ts is a frame plus its time axis, its resolution in seconds, and its start/end/mid convention; time is I64 seconds since the epoch, UTC only — a frame cannot be built from local-time stamps, because the hour that repeats every autumn is not a bug you want in your averaging windows.

The frame itself is typed per column — F64, F32, I64, I32, I16, BYTE, BOOL, text — and each numeric column carries its own missing value inside the type. (A BOOL column carries none, deliberately: a null that silently became FALSE is the exact lie a flags column must refuse, so gaps in booleans are an error with the column named.)

Averaging, honestly

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
C7Series.m9

expected output:

2025-12-01T00:00:00Z  3.100
2025-12-01T01:00:00Z  2.700
2025-12-01T02:00:00Z  1.950
2025-12-01T03:00:00Z  1.650

The output is the hand-checkable answer: 3.100 is the mean of 3.2 and 3.0; the 01:00 window had one valid reading and one gap, so it answers 2.700 — the gap EXCLUDED and the count rule (minCount) in the caller's hands, per chapter 6's policy; nothing invents a value for the missing half hour.

Two design points worth pausing on:

The rest of the timeseries toolkit follows the same shape: MakeContiguous fills missing PERIODS with each column's declared missing value (and refuses disorder, and refuses to invent booleans); the netCDF writer (chapter 8's sibling) emits CF-1.8-clean files with the time zone stated in the units and the window bounds recorded, because this project has been bitten by files that omit both; and a Parquet reader/writer covers the interchange case with pyarrow as its gate.

← Previous: simple math and statistics · Next: data through zarr →