A kitchen scale’s readings jitter by about 0.2 kg, and a 1 kg parcel lands on it. Below, the readings go through averages of 1, 4 and 16 points. Watch the line grow steadier while its jump comes later.
A longer average: less noise, more delay
A scale's load cell read 50 times a second, noise 0.2 kg RMS. A 1 kg parcel lands at t = 2 s.
N = 1: the raw readings. Their noise, 0.2 kg RMS, is a fifth of the parcel.
Describe this picture
One panel of a scale’s load cell read 50 times a second, with noise of 0.2 kg RMS: the reading in kg against time from 0 to 4 s. A 1 kg parcel lands at s. The readings are small dots, the true weight is a thin dashed line, and the average of points is a solid line. The readouts are the number of points , the noise left and the delay.
The clip lasts 14 s. It starts at , the raw readings, whose noise, 0.2 kg RMS, is a fifth of the parcel; the delay is 0.0 samples. The line eases to the 4-point average: the noise halves, to 0.100 kg, and the jump now takes 4 samples and comes 1.5 samples (30 ms) late. Last it eases to the 16-point average: a quarter of the noise, 0.050 kg, but the jump is a 16-sample ramp, 7.5 samples (150 ms) late. While the line moves, the caption is blank. After the clip a slider named “Points N” sets from 1 to 32, with a value like “16 points”. The arrow keys change by 1, Page Up and Page Down by 4, and Home and End jump to 1 and 32. At other values than 1, 4 and 16 the caption reads like “N = 9: noise left 0.067 kg, delay 4.0 samples (80 ms).” The choice is kept in the link, as length.N.
A longer average: less noise, more delay
Picture a kitchen scale. Its load cell is read 50 times a second, so a new reading arrives every 20 ms and Hz. Each reading is off by a little random noise, about kg, using the RMS of How big is a signal (1.3). At s a 1 kg parcel lands on the scale.
Nobody wants a display that jumps around by 0.2 kg. The first fix most people try is the moving average of Difference equations (6.1): show the mean of the last readings.
Why does averaging help? The noise in one reading has nothing to do with the noise in the next. For unrelated noises like these, the powers add: the power of a sum is the sum of the powers. Power here is the mean square of 1.3, the square of the RMS.
So the sum of readings carries times the noise power of one reading. Dividing the sum by divides its power by , which leaves of the power of one reading. The RMS is the square root of the power, so the average keeps
of the noise. Four readings halve it, and sixteen leave a quarter.
The same argument works for any filter that adds up weighted readings, . Each term carries times the noise power of one reading, and the terms add. So the noise that comes out has RMS .
I call the filter’s noise gain. For the average every tap is , so , and the noise gain is as before.
Averaging has a price. The average’s is equal taps, symmetric about the centre . By Linear-phase systems (17.3), symmetric taps delay every frequency by that many samples. So the average reports each change samples late, and it spreads a sudden jump over samples.
The picture at the top of the page runs the scale’s readings through averages of 1, 4 and 16 points.
Watch the noise readout fall while the delay readout grows. Sixteen points keep a quarter of the noise, and the jump is 150 ms late. It is like a phone poll averaged over a week: it is steadier than one day’s poll, but it tells you about the past week, not about today.
The noise left in the picture comes from the formula. The noise on this particular trace measures 0.197, 0.098 and 0.050 kg, close to it.
You can see the delay in the numbers too. The true weight jumps between and , at . The 4-point average reads 0.25, 0.5, 0.75 and 1 kg at to , so it passes the halfway mark at , 1.5 samples late.
After the clip, set yourself with the slider, from 1 to 32.
A 9-point average and its one-multiply twin
A 16-point average has to keep the last 16 readings in memory. Sensor code often uses the leaky integrator of 6.1 instead, with . In sensor code and in statistics it is called the exponential moving average, or EMA.
It stores one number, the last output. Written as , it costs one multiply per reading.
Its impulse response is for , and it never ends. So there is no centre tap to read a delay from.
Instead I use the balance point of , the centre of 17.3. The taps of both filters add up to 1, so the balance point is . I call it the mean delay. For the -point average it is again.
For the EMA, let , the sum of . Subtracting leaves , which is by 6.1’s geometric sum, because shrinks to 0. So , and
The noise gain comes from the same kind of sum. Each is , and the powers add up to . Since ,
Now ask for an EMA that matches an -point average. Equal noise needs . Equal mean delay needs . Solve either one and you get the same answer:
I call this the twin rule. For it gives .
Think of guessing when your bus will come. You could keep a notebook of the last nine trips and average them. Or you could nudge your guess a little after each trip, which needs no notebook. Below, the two work side by side on the scale’s readings.
A 9-point average and its one-multiply twin
The same readings through a 9-point moving average and an EMA, y[n] = 0.8y[n−1] + 0.2x[n].
The readings around the parcel's arrival at t = 2 s.
Describe this picture
One panel of the readings in kg against time from 1 to 3 s, through a 9-point moving average and an EMA, . The readings are small dots and the true weight is a thin dashed line, as before. The average is a solid line labelled “9-point average”, and the EMA is a dashed line labelled “EMA, a = 0.8”. The readouts come in two rows, the noise left by each filter and then the mean delay of each; each reads “not yet” until its line is drawn.
The clip lasts 13 s. At the start only the readings around the parcel’s arrival at s show. Then the average draws: it keeps a third of the noise, 0.067 kg, and its jump is a straight ramp that ends 8 samples (160 ms) after the parcel lands; its mean delay reads 4.0 samples. Then the EMA draws: it leaves the same noise, 0.067 kg, and has the same mean delay, 4.0 samples, but it starts rising at once and creeps the rest of the way. After the clip a slider named “EMA a” sets from 0.50 to 0.95 in steps of 0.01, with a value like “a = 0.80”. The arrow keys change by 0.01, Page Up and Page Down by 0.05, and Home and End jump to the ends. The EMA redraws at once and the average stays. Away from 0.8 the caption reads like “a = 0.90: noise left 0.046 kg, mean delay 9.0 samples: the twin of a 19-point average.” The choice is kept in the link, as twin.a.
Notice that the four readouts come in two equal pairs. The shapes of the jumps differ, though.
The average’s ramp is straight and finishes. The EMA’s step response is of 6.1: it is 0.2, 0.36 and 0.488 of the way after one, two and three samples, and it never quite arrives.
After the clip, set the EMA’s yourself with its slider. Try 0.9: that EMA is the twin of a 19-point average.
The two twins remove the same amount of noise, but not from the same frequencies. The average’s gain is zero at (Frequency response of discrete-time systems, 12.4). In hertz, by Frequency in discrete time (12.1), these nulls sit at
For 9 points at 50 Hz they are the multiples of 5.56 Hz. The EMA’s gain follows from 12.4’s method, as for the leaky integrator there:
The denominator is never zero, so the EMA has no nulls.
Choosing a
There are two common ways to pick . The first starts from a time constant. In Differential equations and analog systems (6.2) the leaky integrator is the step-by-step copy of an RC circuit, with . Here is the time constant , so
At 50 Hz, a time constant of 0.2 s gives . That EMA leaves 0.045 kg of noise and has a mean delay of 9.5 samples, 190 ms. It is the twin of a 20-point average.
The second starts from an equivalent and uses the twin rule. The pandas library’s ewm(span=N) sets , which is the same rule. The internet’s TCP protocol tracks the round-trip time of its packets with an EMA of (RFC 6298). That is the twin of a 15-point average.
The average’s nulls are useful by themselves. Mains power puts a hum at 50 Hz, and often at 100 Hz, 150 Hz and so on. Sample at 1 kHz and average 20 points, exactly one 20 ms mains period. The nulls fall at every multiple of 50 Hz, so the hum and all its harmonics are removed.
In a country with 60 Hz mains, the same average keeps 0.157 of the hum. Averaging 100 ms instead, 100 points at 1 kHz, puts a null at every multiple of 10 Hz, which covers both 50 and 60 Hz. That is why bench multimeters measure over a whole number of mains cycles.
A median ignores spikes
Not every problem is steady noise. Sometimes a single reading is far off, because a wire made a bad contact or someone bumped the scale. I call such a reading a glitch. An average spreads a glitch into a bump that lasts samples.
There is a smoother that ignores glitches. Sort the last 5 readings and take the middle one, their median. For 0, 0, 2, 0, 0 the sorted list is 0, 0, 0, 0, 2, and the middle value is 0. A median filter outputs the median of the last readings at every sample.
With 5 readings the middle value is the third. One glitch, or two, sort to an end of the list and never reach the middle. A jury’s middle score works the same way: one judge’s wild mark does not move it. Below, a 5-point average and a 5-point median work on the same readings.
A median ignores spikes
Readings with three glitches, through a 5-point average and a 5-point median of the last 5 readings.
The reading steps from 0 to 1 at n = 20. Glitches: +2 at n = 6, +2 at n = 12 and 13, and −2 at n = 30.
Describe this picture
Two stacked panels share the sample axis, from 0 to 39, for readings with three glitches. The first draws the readings as stems with dot heads. The second draws the outputs of a 5-point average, as stems with square heads, and of a 5-point median of the last 5 readings, as stems with diamond heads, side by side at each sample. The readouts are each filter’s biggest bump: the largest distance between its output and its output for the same readings without glitches. There is no control.
The clip lasts 13 s. At the start only the readings show: a step from 0 to 1 at , and glitches of +2 at , +2 at and 13, and −2 at . Then the average builds sample by sample. It spreads each glitch over 5 samples, into bumps of 0.4, and 0.8 where two sit together, and the step becomes a 5-sample ramp; its readout is 0.80. Then the median builds: one or two glitches never reach the middle of 5 values and vanish, and the step stays sharp, 2 samples late; its readout is 0.00.
Notice that the two glitches side by side give the average its biggest bump, 0.8. Each glitch adds to every average that contains it, and two together add 0.8. The median does not move at all, and its step is as sharp as the input’s.
The median pays for this by giving up linearity. Apply the scale-and-add test of System properties (4.2, “Does scaling and adding pass through?”) to a 3-point median.
Take two windows of readings, and . Each has median 0, so the medians add to 0. But the sum of the windows is , whose median is 1.
So a median filter is not linear, and it has no impulse response that describes it. Feed it a single 1 and it outputs only zeros, yet its output for a step is a step. Noise gain, nulls and frequency response do not apply to it. On a flat stretch, a median of readings removes bursts of up to glitches in a row; a burst of outweighs the rest and survives.
Three smoothers, one trace
Here are all three on the scale’s readings from the first instrument, with four glitches added. Three are 1.5 kg up, at samples 40, 41 and 150, and one is 1.5 kg down, at sample 170. Each smoother has 9 points, or the 9-point twin, so all three lag by about 4 samples.
Look at the glitches at 0.8 s. The average turns the pair into a flat bump of 0.33 kg that lasts 9 samples. The EMA jumps by 0.54 kg and then creeps back.
The median barely moves, and its step at 2 s is the sharpest of the three. But it keeps the most noise, 0.42 of it, because for noise like this the middle value of 9 readings is a rougher estimate than their mean.
So which one should you choose? If the problem is noise and the delay does not matter, use an average, or an EMA when memory or computing time is short, as on a small microcontroller. If the problem is a fixed hum, average over exactly its period. If the problem is glitches or dropouts, use a median, often followed by an average to take out the noise that is left.
Worked example
Let’s work out the scale’s 9-point average and its twin by hand, at Hz with kg.
Noise and delay of the average. The noise left is kg. The delay is samples, which is ms.
Nulls of the average. They sit at multiples of Hz: 5.56, 11.11, 16.67 and 22.22 Hz, all below the top frequency of 25 Hz.
At 25 Hz itself, and . The nine taps alternate in sign, five plus and four minus, so the gain is . Solving for the gain numerically puts the −3 dB point at 2.47 Hz.
The twin. The twin rule gives . Its noise gain is , so it also leaves 0.067 kg, and its mean delay is samples. At 25 Hz, , so the EMA’s squared gain is . Its gain is , the same as the average’s.
The EMA’s −3 dB point. Set the squared gain to : . Rearranged, this gives
So rad/sample, and Hz. The EMA’s gain falls faster at first than the average’s, but it never reaches zero.
From a time constant, and TCP’s twin. For s, , the noise gain is (0.045 kg), and the mean delay is samples (190 ms). Its twin has points. For TCP’s , the twin has and the noise gain is .
Median against average. On the closing figure’s readings, the three smoothers compare like this. The raw readings have 0.203 kg of noise on the flat stretches.
| Smoother | Biggest bump (kg) | Noise left (kg) | Share of the raw noise |
|---|---|---|---|
| 9-point average | 0.333 | 0.067 | 0.332 |
| EMA, | 0.540 | 0.070 | 0.343 |
| 9-point median | 0.198 | 0.085 | 0.417 |
The average and the EMA keep about a third of the noise, as the formula predicts. The median keeps more noise and moves least at the glitches.
The maths behind it · Toeplitz matrices
Write the readings as a column of numbers. The moving average is then a banded Toeplitz matrix acting on that column, the matrix view of convolution in Discrete convolution (5.2): each row holds entries of . The EMA is a lower-triangular Toeplitz matrix with entries down each column. The median is not a matrix at all: it fails linearity, so no matrix can do what it does.
Where you’ll meet this
Sensor firmware is full of these three. A temperature or weight reading on a small microcontroller is often an EMA, because it needs one stored number. A display that must not flicker uses a short average. A reading that sometimes glitches gets a median first.
The internet’s TCP protocol estimates round-trip time with an EMA of , as above. Rolling means of daily counts, such as a 7-day average of cases or sales, are moving averages whose nulls remove the weekly pattern. Median filters clean isolated bad pixels from images, which is the subject of Image filtering (28.2).
Smoothers with unequal weights, such as the Savitzky–Golay filter, which fits a polynomial to each window, come up with Special FIR filters (19.4). Moving averages built in hardware, called CIC filters, are in Polyphase structures (22.4). The Kalman filter, whose steady state is an EMA, is in RLS and the Kalman filter (26.4). A full sensor chain is in Sensor signal conditioning (32.2).
The maths behind it · robust estimators
The moving average is the rolling mean of time-series work, and the EMA is its exponentially weighted moving average; pandas’ ewm(span=N) uses the twin rule. The median is a robust estimator: almost half of the values can be wild before it moves far, while one wild value moves the mean.
Reference card
| Quantity | Formula | Notes |
|---|---|---|
| Moving average | delay samples | |
| Noise left | average: | |
| Average’s nulls | a whole mains period removes hum | |
| EMA | one multiply, one stored value | |
| EMA noise gain, mean delay | ; samples | |
| EMA from | 6.2’s discrete copy | |
| Twin of an -point average | same noise, same mean delay | |
| Median | middle of the last readings | not linear; removes bursts shorter than |