开发者

Matlab Fill previous value if missing value (or zero)

开发者 https://www.devze.com 2023-04-03 07:49 出处:网络
I have a vector containing a time series with different values and some missing values inbetween that are set to zero:

I have a vector containing a time series with different values and some missing values inbetween that are set to zero:

X=[0,0,2,0,5,0,0,0,4,0];

I want to create a new vector where the missing values (zeros) are populated by the previous value if one exist so that I get a new vector looking like:

Z=[0,0,2,2,5,5,5,5,4,4];

I have been browsing through the Matlab help and forums like this to find a neat and suitable function that would solve this for me with a one line solution or similar, but I have failed to do so. I can solve the problem开发者_JAVA技巧 through a few different steps according to below but I am guessing that there must be a better and easier solution available?

Current solution:

X=[0,0,2,0,5,0,0,0,4,0];
ix=logical(X);
Y = X(ix);
ixc=cumsum(ix);
Z=[zeros(1,sum(~logical(ixc))) Y(ixc(logical(ixc)))];

This does the trick, but it seems like an overly complicated solution to a simple problem, so can anyone help me with a better one? Thanks.


Here's a somewhat simpler version using cumsum:

X=[0,0,2,0,5,0,0,0,4,0];

%# find the entries where X is different from zero
id = find(X); 

%# If we want to run cumsum on X directly, we'd 
%# have the problem that the non-zero entry to the left
%# be added to subsequent non-zero entries. Thus, 
%# subtract the non-zero entries from their neighbor 
%# to the right 
X(id(2:end)) = X(id(2:end)) - X(id(1:end-1));

%# run cumsum to fill in values from the left
Y = cumsum(X)

Y =
     0     0     2     2     5     5     5     5     4     4


Here's a little something I wrote up. Does this do the trick?

% INPUT: the array you would like to populate
% OUTPUT: the populated array

function popArray = populate(array)

popArray = array;

% Loops through all the array elements and if it equals zero, replaces it
% with the previous element
%
% Since there is no element before the first to potentially populate it, this
% starts with the second element.
for ii = 2:length(popArray)
    if array(ii) == 0;
        popArray(ii)= popArray(ii-1);
    end
end

disp(popArray);


Let me suggest another vectorized solution (though I like the one by @Jonas better):

X = [0 0 2 0 5 0 0 0 4 0]

id = find(X);
X(id(1):end) = cell2mat( arrayfun(@(a,b)a(ones(1,b)), ...
    X(id), [diff(id) numel(X)-id(end)+1], 'UniformOutput',false) )
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号