Fill gaps using Nan in for loop

조회 수: 3 (최근 30일)
Jaehwi Bong
Jaehwi Bong 2019년 9월 19일
댓글: Jaehwi Bong 2019년 9월 20일
I have a time series with some gaps in it and i want to fill the gaps with NaN in loop.
For example, my data is
data = [0 50;
1 100;
2 200;
3 300;
5 500;
6 600;
7 700;
10 1000;
0 30;
2 20;
6 40]
First column and second column refer to time and signal value. But it has 2 objects. (I have thousands objects.). One was begun from 0(first row), the other one was begun 0(9th row). But sometimes it began from 2 or whatever. The solution code should detect the next result when the value of 1st column decreased.
I'd like to change it as a new_data.
new_data = [1 100;
2 200;
3 300;
4 NaN;
5 500;
6 600;
7 700;
8 NaN;
9 NaN;
10 1000;
0 30;
1 NaN;
2 20;
3 NaN;
4 Nan;
5 Nan;
6 40]
How can I make it?
If anyone can help, it would be greatly appreciated.
Thank you!

채택된 답변

Stephen23
Stephen23 2019년 9월 20일
편집: Stephen23 2019년 9월 20일
Using two accumarray calls:
>> data = [0,50;1,100;2,200;3,300;5,500;6,600;7,700;10,1000;0,30;2,20;6,40]
data =
0 50
1 100
2 200
3 300
5 500
6 600
7 700
10 1000
0 30
2 20
6 40
>> D = diff(data(:,1),1,1);
>> F = @(v){(v(1):v(end)).'};
>> M = [cell2mat(accumarray(cumsum([true;D<0]),data(:,1),[],F)),accumarray(cumsum([1;max(1,D)]),data(:,2),[],[],NaN)]
M =
0 50
1 100
2 200
3 300
4 NaN
5 500
6 600
7 700
8 NaN
9 NaN
10 1000
0 30
1 NaN
2 20
3 NaN
4 NaN
5 NaN
6 40

추가 답변 (1개)

Shunichi Kusano
Shunichi Kusano 2019년 9월 20일
Hi Jaehwi,
I wrote code. hope this helps.
data = [0 50; 1 100; 2 200; 3 300; 5 500; 6 600; 7 700; 10 1000; 0 30; 2 20; 6 40;];
% find where the value decreases
decreaseIndex = find(diff(data(:,1)) < 0);
% new object begin with decreasing the value
objectBeginIndex = [1, decreaseIndex+1];
%% loop for each objects
objectsNum = length(objectBeginIndex);
fullset = [0:10]';
fulldata = NaN(11*(objectsNum-1), 2); % up to the second last
fulldata(:,1) = repmat(fullset, objectsNum-1, 1);
for i = 1:objectsNum
if ~(i == objectsNum)
tempdata = data(objectBeginIndex(i):objectBeginIndex(i+1)-1,:); % extract single object
existDataIndex = find(ismember(fullset, tempdata(:,1))); % find where the data exist
fulldata((i-1)*11+existDataIndex, 2) = tempdata(:,2); % place the data
else % if i is last, up to existing number, not to 10.
tempdata = data(objectBeginIndex(i):end,:);
maxi = tempdata(end,1);
existDataIndex = find(ismember([0:maxi]', tempdata(:,1)));
lastdata = [[0:maxi]', NaN(maxi+1, 1)]; % up to the second last
lastdata(existDataIndex,2) = tempdata(:,2);
fulldata = [fulldata; lastdata];
end
end
  댓글 수: 1
Jaehwi Bong
Jaehwi Bong 2019년 9월 20일
Thank you Shunichi!
I'm trying with a data that have 3 objects. But it keep complaining at the line " repmat". I've revised some line to use it. Do you mind this code?
data2 = [0 50; 1 100; 2 200; 3 300; 5 500; 6 600; 7 700; 10 1000; 0 30; 2 20; 6 40; 0 20; 1 10; 5 50;];
% find where the value decreases
decreaseIndex2 = find(diff(data2(:,1)) < 0);
decreaseIndex = zeros(length(decreaseIndex2)+1,1);
decreaseIndex(2:end) = decreaseIndex2(1:end);
decreaseIndex(1) = 0;
% new object begin with decreasing the value
for k = 1:length(decreaseIndex)
objectBeginIndex(k,1) = decreaseIndex(k)+1;
end
%% loop for each objects
objectsNum = length(objectBeginIndex);
fullset = [0:length(data2)]';
fulldata = NaN(length(data2)*(objectsNum-1), 2);

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Logical에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by