I have some data in a list that are non-numeric. I want to replace the bad data with a linear interpolation from the surrounding data. The non-numeric data can be easily identified. There may be more than "one section" (i.e. continuous sub-list) of bad data in the list. For example
(*if the list contained the following*)
testy = {1.1, 2.4, 3.5, 2.5, "xx", "xx", "xx", 4.5, 8.5, "xx", "xx", "xx",
4.5, "xx", 8.5};
(*want to change it to*)
{1.1, 2.4, 3.5, 2.5, 3.0, 3.5, 4.0, 4.5, 8.5, 7.5, 6.5, 5.5,
4.5, 6.5, 8.5};
I have a very basic working approach to address this (below) but there are probably better ways to do this. There are special cases that this doesn't handle, such as if the first point, the last point, or all of the data is bad -- that is not a priority for this question. Those can be handled separately.
In this approach, I couldn't find a "nice" way to find the first and last points of every "section" of bad data. So, at the moment my approach is to run this routine multiple times until all the bad data is removed.
addition to original post: The test examples has just a few entries. The application will have between 500 and 10000 elements per row and around 7000 rows.
(*test data*)
testy = {1.1, 2.4, 3.5, 2.5, "xx", "xx", "xx", 4.5, 8.5, "xx", "xx",
"xx", 4.5, "xx", 8.5};
testyBefore = testy;
npts = Length@testy;
(*postions of bad data*)
xxList = Flatten@Position[testy, "xx"];
(*first and last position of a continuous run of bad data *)
k = 1 + LengthWhile[ Range[npts - 1],
xxList[[# + 1]] == 1 + xxList[[#]] & ];
iStart = First@xxList;
iEnd = xxList[[k]];
nBad = 1 + (iEnd - iStart );
{iStart, iEnd, nBad};
(*linear interpolation along line*)
y0 = testy[[iStart - 1]];
yN = testy[[iEnd + 1]];
yStep = (yN - y0) /(1 + nBad) ;
(*update data*)
iList = Range[iStart, iEnd];
yiList = (y0 + # yStep) & /@ Range[nBad];
(testy[[iList[[#]] ]] = yiList[[#]]) & /@ Range[nBad];
testyAfter = testy;
(*summary*)
Grid[{ Prepend[ testyBefore, "Before"], Prepend[testyAfter, "After"] }, Frame -> All]
The result of this is to replace only the first section of bad data. The process could then be repeated.
Thanks for your recommendations.