Add a moving average to a CSV
Tick one or more numeric columns and this page appends a smoothed version of each, keeping every original column and every row in place. Simple or exponential, trailing or centered, with a window and a minimum-periods rule you set yourself. The file is read and smoothed inside this browser tab, and nothing is uploaded anywhere.
Noisy because the grain is too fine? Roll the series up to weeks or months
A moving average is four choices wearing one name
Ask for a moving average and most tools hand you a trailing simple average over a fixed window, blank until the window fills, on one column. That is a defensible default. It is a poor only option, because the three settings it hides are the ones that change the answer, and people argue about them for good reasons. All four are on the page.
- Simple or exponential. A simple average gives every row in the window the same weight. An exponential average weights the most recent row most and fades older ones geometrically, so when the underlying level steps up it catches up in a few rows rather than in a full window. The smoothing factor is the standard span form, alpha equals 2 divided by the window plus 1.
- Trailing or centered. Trailing looks only backwards, which is exactly what you knew at the time and therefore the right choice for anything that drove a decision. Centered puts half the window either side of the row, which removes the half-window lag and is the honest choice for a chart of what happened. The same data smoothed both ways puts its peak in two different places.
- Minimum periods. How many real values a window needs before it prints a number. Set it to 1 and the opening rows average whatever exists so far, which is what a spreadsheet user expects. Set it to the window size and the opening rows go blank, which is what most statistical libraries do. Neither is wrong; leaving the choice out of the interface is.
- How many columns. Tick as many as you like. Every ticked column gets its own smoothed column in the same output file, on the same rows, in the original row order.
One thing is not a choice: the output keeps your whole file. Every original column, every original row, in the original order, with the new columns appended on the right. That means the result still joins back to whatever it came from, and you can drop it straight into a chart or a spreadsheet without reconciling row counts.
Worked example: seven rows and a 3-row window
Here is week.csv. Seven values, small enough that the arithmetic below is all doable in your head:
day,orders
Mon,10
Tue,14
Wed,9
Thu,17
Fri,13
Sat,4
Sun,3
Set the window to 3, leave the method on Simple, the alignment on Trailing and the minimum periods on 1. Monday has only itself, so it averages to 10. Tuesday averages 10 and 14, which is 12. Wednesday is the first full window: 10 plus 14 plus 9 is 33, over 3, so 11. Thursday is 14 plus 9 plus 17, which is 40 over 3. The output is:
day,orders,orders_ma
Mon,10,10
Tue,14,12
Wed,9,11
Thu,17,13.3333
Fri,13,13
Sat,4,11.3333
Sun,3,6.6667
Check the last one: 13 plus 4 plus 3 is 20, over 3 is 6.6667. Numbers are written with up to four decimals and trailing zeros trimmed, so 13 stays 13 rather than becoming 13.0000, and values in the thousands are held to two decimals because a fourth decimal on a revenue figure is noise. Grouping commas are stripped, since a comma inside a CSV cell is a problem you do not need.
Now switch the alignment to Centered and nothing else. Monday now averages Monday and Tuesday, so 12. Sunday averages Saturday and Sunday, so 3.5. The column becomes 12, 11, 13.3333, 13, 11.3333, 6.6667, 3.5. Look at where the peak sits. Trailing puts its high point of 13.3333 on Thursday, one day after Thursday's actual spike of 17 started building. Centered puts the same 13.3333 on Wednesday, in the middle of the Tue-to-Thu run that produced it. That one-row shift is the half-window lag, and on a 7-day window it is three days, which is enough to make a smoothed line appear to peak after the event it is describing.
Set the minimum periods to 3 with trailing alignment and the first two cells go empty instead: , then , then 11, 13.3333, 13, 11.3333, 6.6667. The summary strip changes from no blank opening rows to first 2 rows blank (minimum 3 periods), so you never have to count them yourself.
Finally, switch the method to Exponential with the same window of 3. Alpha is 2 over 4, or 0.5, so each row is the midpoint of the previous average and the new value. Starting from 10: Tuesday is 10 plus half of 4, so 12. Wednesday is 12 plus half of minus 3, so 10.5. Thursday is 10.5 plus half of 6.5, so 13.75. The full column, in a new column named orders_ema, is 10, 12, 10.5, 13.75, 13.375, 8.6875 and 5.8438. Compare the weekend to the simple version: the exponential average has already fallen to 5.8438 by Sunday while the simple one is still at 6.6667, because it is still carrying Friday's 13 at full weight.
Choosing a window, and living with the lag
The window is the only setting with no defensible default, because it depends entirely on what you are trying to remove. The box starts at 7 because daily data with a weekend in it is the most common file that arrives here, and a 7-row window cancels the day-of-week pattern exactly. For hourly data, 24 does the same job for the daily cycle. For monthly data, 12 removes seasonality. For anything without a cycle, pick the shortest window that makes the line readable, because every extra row of window is another row of lag and another real feature flattened away.
Lag is worth being precise about, since it is the cost you pay for the smoothing. A trailing simple average of width w is centered on the point w minus 1, over 2 rows in the past. A 7-row trailing average lags by 3 rows. A 30-row one lags by about 15, which on daily data is half a month, and a metric that turned two weeks ago will still look flat. If the point of the chart is to show when something changed, use Centered. If the point is to reconstruct what a dashboard would have shown at the time, use Trailing and accept the lag knowingly.
An exponential average has lag too, but it is spread out rather than sharp. With alpha at 2 over the window plus 1, roughly 86 percent of the weight sits inside the most recent window's worth of rows and the rest tails off behind. After a step change it closes most of the gap within a window and keeps creeping the rest of the way. That is why monitoring tools reach for it: it reacts quickly without the jitter of the raw series, and it needs only one number in memory rather than a whole window.
An even window has no exact middle. When you center one, the tool takes one more row from the future side than from the past, which is what pandas does with center=True, so results line up if you check this against a notebook. If the symmetry matters to you, use an odd window.
Gotchas worth knowing
- Row order is the time order. The window is a window over rows, not over dates. If your file is sorted by customer or by amount, the smoothed column is arithmetic performed on nothing meaningful. Sort by the date column first, and if the file has several rows per day, resample it to one row per day before you smooth it.
- Gaps in time are invisible to it. Two rows next to each other are treated as adjacent periods whether they are one day apart or four months apart. A series with missing days needs those days present, blank or zero, before a 7-row window means 7 days.
- Blanks are skipped, not zeroed. A missing number inside the window is left out of the average and out of the count, and the count is what the minimum-periods rule is tested against. You get a warning naming the column and the number of rows without a value.
- A window of 1 is refused. It would return the column unchanged, so the tool asks for 2 or more rather than handing you a duplicate. Windows above 100,000 rows are refused too.
- A window wider than the file gets a warning, not an error. Every value becomes the average of the whole column, which is a flat line. That is sometimes what you meant, so it runs, and the warning says what happened.
- Centered is ignored by exponential. The setting is hidden when you pick Exponential, and on the rare path where it survives a switch you get a warning saying it was ignored. An exponential average has no future term to center around.
- Do not smooth twice. Feeding a smoothed column back in widens the effective window in a way that is hard to reason about and flattens genuine turning points. Pick one window and one method.
- Nothing leaves the tab. Parsing, windowing and writing all happen in your browser. There is no upload on this page.
Frequently Asked Questions
Simple or exponential: which should I pick?
Simple when every period in the window deserves equal weight, which is most reporting. Exponential when you care about reacting quickly to a change in level, because an exponential average weights recent values more heavily and settles on a new level in a handful of periods instead of waiting for the whole window to turn over. Monitoring, alerting and anything you look at daily tends to want exponential. A chart of last quarter tends to want simple.
What does Centered do, and why does it disappear for exponential?
A trailing average at row 40 uses rows 34 to 40, so its value belongs to the middle of that stretch but is printed against row 40. That is a lag of half the window, and on a chart it shifts every peak to the right. Centered puts the window around the row instead, so a 7-row window at row 40 uses rows 37 to 43, and peaks stay where they happened. The setting is hidden for the exponential method because an exponential average is a recursive filter over the past and has no future term to balance. If a centered setting is somehow still set when you switch, the tool tells you it was ignored rather than pretending.
Why are the first rows of my moving average blank?
Only if you asked for that. Minimum periods starts at 1, which means the very first row averages the one value available, the second averages two, and so on until the window fills. Set minimum periods to match the window and the opening rows go blank instead, which is the convention most statistical libraries default to and the right choice when a three-value average printed in a column labelled seven-day would mislead someone. The summary line names how many opening rows came back blank so the choice is never invisible.
What smoothing factor does the exponential average use?
Alpha equals 2 divided by the window plus 1, the standard span form. A window of 3 gives alpha 0.5, a window of 7 gives 0.25, a window of 19 gives 0.1. Each new value is the previous average plus alpha times the difference between the new value and that average. The series is seeded from the first real value rather than from a zero or from an average of the first window, so the line starts on the data instead of climbing up to it.
Can I smooth several columns in one pass?
Yes. Columns to smooth is a multi-select and each ticked column gets its own new column appended, all using the same method, window, alignment and minimum periods. This matters more than it sounds: smoothing three columns in three separate passes gives you three files that you then have to line up row by row, and any sorting difference between passes puts the wrong average next to the wrong row. One pass, one file, original row order preserved.
What are the new columns called, and is anything overwritten?
The source column name plus a suffix, so revenue becomes revenue_ma for a simple average and revenue_ema for an exponential one. Type your own suffix in the box if you want something else, such as _7d. Nothing is ever overwritten: if the file already has a column with the name the tool wants, the new one gets a number appended, becoming revenue_ma_2, and a warning tells you it happened. Every original column stays where it was, in the original order.
What happens to blank cells inside the window?
They are skipped, not counted as zero. A blank in a revenue column means nobody recorded a number, and averaging it as zero drags the line down by an amount no reader can see. So a 7-row window containing two blanks averages the five real values, and those five are what the minimum-periods rule is checked against. You also get a warning naming the column and how many rows in it held no number.
Does my CSV get uploaded?
No. This page has no upload endpoint. The file is parsed, the windows are rolled and the new columns are written by JavaScript inside your own browser tab, and the download is built from memory in that same tab. Nothing is stored between visits, so a reload gives you an empty drop zone rather than your last run.
Related
Get a line you can actually read
Free, no account, no upload. Pick the method, set the window, and keep every column you started with.
Back to the smoother