Fill the gaps in a number series by linear interpolation

Paste a column with blanks or NA markers in it and get it back with every gap filled on the straight line between its two nearest known values. Two-column data is interpolated against the real x spacing, a max-gap limit stops long holes being invented, and the values you typed come back untouched.

Try:
Filled series

About this tool

linear-interpolate-gaps fills the holes in an ordered numeric series. Every missing cell is replaced by the value on the straight line drawn between the nearest known value before it and the nearest known value after it — the same thing a spreadsheet's fill-series does between two anchors, and the same thing interpolate(method="linear") does in a dataframe.

Paste a column of readings with blanks, NA, null or - in it. What comes back is the same column with the gaps filled. The numbers you typed are echoed verbatim: a value entered as 1.00 comes back as 1.00, not 1, so nothing you did not ask for gets reformatted.

Two-column data is the part most quick converters get wrong. If every row has exactly two fields, they are read as x,y pairs and the interpolation uses the real x spacing. A sensor that logged at minute 0, 5, 10 and 20 is not the same series as four evenly spaced rows, and the answers differ.

Worked example

Two readings, four missing months between them, defaults everywhere:

10




20

Result:

10
12.5
15
17.5
20

Now the same shape with real timestamps, as x,y rows:

minute,reading
0,20
5,
10,
20,50

Result — the step from 10 to 20 is twice as wide as the others, so the values are not evenly spaced:

0,20
5,27.5
10,35
20,50

Choosing the options

Everything runs locally in WebAssembly in your browser. Nothing is uploaded, there is no account, and there is no daily quota.

Limits and edge cases

FAQ

How is this different from a forward fill?

A forward fill copies the last known value forward, so a gap between 10 and 20 becomes 10, 10, 10, 20 — a staircase. Linear interpolation draws the line, so it becomes 10, 12.5, 15, 17.5, 20 — a ramp. If you want the staircase behaviour at the ends of the series, set Gaps outside the known range to hold; that is exactly a forward/backward fill for the cells that have no second anchor.

Why did my long gap only fill partway?

Because Max gap to fill clipped it. With a limit of 2 and direction both, a run of seven blanks is filled two cells in from the left and two in from the right, and the three in the middle stay empty — the ends are close enough to a real reading to trust, the middle is not. Set the limit to 0 to fill everything, or switch the direction to forward or backward to fill from one side only. The json output names every run it refused and why.

My timestamps are not evenly spaced. Does that matter?

It matters a lot, and it is handled. Paste the data as two columns — x,y, one pair per row — and the interpolation uses the real distance along the x axis instead of the row number. Between (0, 20) and (20, 50), the value at x = 5 is 27.5, not the 35 you would get by treating the rows as equal steps. Dates need converting to numbers first (a day index or an epoch value); the x column has to be numeric.

What happens to blanks at the very start or end of the series?

By default they are left blank. Those cells sit outside the known range, so there is no pair of anchors to draw a line between, and filling them means extrapolating — inventing data past your last measurement. Choose hold to repeat the nearest known value, or extrapolate to extend the slope through the two nearest known points. Note that extrapolate can run negative, so check the result against what the quantity can physically be.

Can I use my own missing marker, like -999?

Yes. Put it in Extra missing markers — comma-separated, case-insensitive — and it is treated as a gap on top of the built-in list (blank, na, n/a, nan, null, none, nil, -, --, ?). This is worth doing for logger sentinels: without it, -999 parses as a perfectly valid number and gets used as an anchor, which drags the interpolated values around it wildly out of range.

How do I tell which numbers were filled and which were mine?

Switch Output to csv and every row comes back with a status of known, filled or missing, so the generated values are labelled in the data itself. The json output goes further: counts of each status, the numeric array with unfilled gaps as null, and a report of every gap run giving its start, end, length, kind (leading, interior or trailing) and how many cells were filled.

Is my data uploaded anywhere?

No. The whole calculation is a WebAssembly module running in your browser tab, so the series never leaves your machine. The same code ships in the gizza CLI if you would rather fill gaps from a terminal or a script.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool linear-interpolate-gaps "10



20"

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/linear-interpolate-gaps/?input=10%0A%0A%0A%0A20&layout=auto&max_gap=0&direction=both&edges=leave&na_tokens=missing%2C-999&decimals=6&output=values

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.