This is an attempt because more clarity is needed in terms of all possible scenarios to consider, based on different input data and how to understand the "extrapolation" process. This approach understands as extrapolation the average of two values (lower and greater), but the idea can be customized to any other way to calculate it. Per tags listed in the question I assume there is no Excel version constraint. This is O365 solution:
=LET(sm, A2:A10, st, B2:B10, jph, C2:C10, smx, F1:J1, sty, E2:E4, NULL, "",
GETLk, LAMBDA(x,y,mode, FILTER(jph, (st=y)
* (sm = INDEX(sm, XMATCH(x, sm, mode))), NULL)),
GET, LAMBDA(x,y, LET(f, FILTER(jph, (jph=GETLk(x,y, 1))
+ (jph=GETLk(x,y, -1)), NULL), IF(@f=NULL, NULL, AVERAGE(f)))),
HREDUCE, LAMBDA(yi, DROP(REDUCE("", smx, LAMBDA(ac,x,
HSTACK(ac, GET(x, yi)))),,1)),
DROP(REDUCE("", sty, LAMBDA(ac,y, VSTACK(ac, HREDUCE(y)))),1))
The above formula spills the entire result, I don't think for this case you can use a LOOKUP
-like function.
Here is the output:

The highlighted cells where the average is calculated.
Explanation
The main idea is to use DROP/REDUCE/HSTACK/VSTACK
pattern to generate the grid. Check my answer to the following question: how to transform a table in Excel from vertical to horizontal but with different length on how to apply it.
We use two user LAMBDA
functions to abstract some calculations:
GETLk(x,y,mode)
, filters jph
name based on %SMALL and Stations columns values, based on input values x
(x-axis value from the grid), y
(y-axis value form the grid) respectively. The third input argument mode
, is for doing the approximate search in XMATCH
(1
-next largest, -1
next smallest). In case the value exist in the input table, XMATCH
returns the same value in both cases.
GET(x,y)
has the logic to find the value or if the value doesn't exist to calculate the average. It uses the previous LAMBDA
function GETLk
. We filter for jph
values that match the input values (x
,y
), but we use an OR condition in the FILTER
(+
), to select both lower or greater values. If the value exist, returns just one value otherwise two values are returned by FILTER
(f
). Finally if f
is not empty we return the average, otherwise the value we setup as NULL
.
HREDUCE
: Concatenate the result by columns for a given row of the grid. Check the referred question for more information about it.