Replace missing data
I know this is a duplicate but since I failed to find it with ten minutes of searching:
x = {2, 0, 0, 7, 0, 3, 0, 0, 1};
FoldList[If[#2 == 0, #, #2] &, x]
{2, 2, 2, 7, 7, 3, 3, 3, 1}
To handle leading zeros:
x = {0, 7, 0, 3, 0, 0, 1};
FoldList[If[#2 == 0, #, #2] &, SelectFirst[x, # != 0 &], Rest @ x]
{7, 7, 7, 3, 3, 3, 1}
The case without leading zeroes can also be handled nicely using Split
, borrowed from Leonid's method for Fill out blanks with a upcoming number in a list?:
x = {2, 0, 0, 7, 0, 3, 0, 0, 1};
Join @@ Accumulate /@ Split[x, #2 == 0 &]
{2, 2, 2, 7, 7, 3, 3, 3, 1}
The leading zeros can be handled by prepending the first non-zero value to the list, then applying Rest
at the end.
For Q2 I think all you need is to convert either method to a function and map it:
fn[x_] := FoldList[If[#2 == 0, #, #2] &, SelectFirst[x, # != 0 &], Rest @ x]
fn /@ {{2, 0, 0, 7, 0, 3, 0, 0, 1}, {0, 1, 2, 7, 0, 3, 0, 0, 1}}
{{2, 2, 2, 7, 7, 3, 3, 3, 1}, {1, 1, 2, 7, 7, 3, 3, 3, 1}}
TemporalData + MissingDataMethod
ClearAll[interpolateMissing]
interpolateMissing = Quiet @ TemporalData[# /. 0 -> Missing[], Automatic,
MissingDataMethod -> {"Interpolation", InterpolationOrder -> 0}]["States"] &;
Examples:
interpolateMissing @ {1, 0, 2, 0, 3}
{{1, 1, 2, 2, 3}}
interpolateMissing @ {0, 7, 0, 3, 0, 0, 1}
{{7, 7, 7, 3, 3, 3, 1}}
interpolateMissing @ {0, 0, 0, 0, 7, 0, 3, 0, 0, 1}
{{7, 7, 7, 7, 7, 7, 3, 3, 3, 1}}
At the price of extra pair braces in the output when the input is a list, we get the second requirement
How can I expand it to go over matrices of equal-length-vectors?
for free, since interpolateMissing
works as is when the input is an array:
interpolateMissing @ {{1, 0, 2, 0, 3, 0, 1}, {0, 7, 0, 3, 0, 0, 1}}
{{1, 1, 2, 2, 3, 3, 1}, {7, 7, 7, 3, 3, 3, 1}}
Note: Quiet
is used to suppress the following warning:
InterpolatingFunction::dmval: Input value {0} lies outside the range of data in the interpolating function. Extrapolation will be used. >>
By the way, Extrapolation
is exactly what we need to handle cases with leading zeros according to requirement (3).