Select nearest non zero value in column
12 ビュー (過去 30 日間)
古いコメントを表示
Hi, I have a matrix of which the last column consists mainly of zeros and an occasionally non zero value. In a For loop I use each loop the next row for calculations, but for the last column I want to select the closest non zero value in that column. How should I do that? Thanks in advance!
5 件のコメント
the cyclist
2018 年 11 月 1 日
Is it correct that given the input
b = [0 0 0 2 0 0 0 0 0 3 0]'
we could create the output
b2 = [2 2 2 2 2 2 2.5 3 3 3 3]'
then you would be all set?
Kevin Chng
2018 年 11 月 1 日
編集済み: Kevin Chng
2018 年 11 月 1 日
My solution is coming from hard code. I would like to see any other shorter solution.
b = [0 0 0 2 0 0 0 0 0 3 0]';
ind = find(b>0);
if numel(ind)>1
indaverage2(1) = 1;
for i=1:1:numel(ind)-1;
indaverage1(i+1) = (ind(i)+ind(i+1))/2;
indaverage2(i+1) = floor((ind(i)+ind(i+1))/2);
end
k=1;
indaverage2(end+1) = numel(b);
for i=1:1:numel(ind)
valueforcalculation(indaverage2(i):indaverage2(i+1)) = b(ind(i)) ;
end
for i=1:1:numel(indaverage1)-1
if floor(indaverage1(i+1))==indaverage1(i+1)
valueforcalculation(indaverage1(i+1)) = (b(ind(i))+b(ind(i+1)))/2;
end
end
elseif numel(ind)==1
valueforcalculation(1:numel(b)) = b(ind);
elseif numel(ind)==0
valueforcalculation(1:numel(b)) = 0;
end
採用された回答
Bruno Luong
2018 年 11 月 2 日
編集済み: Bruno Luong
2018 年 11 月 2 日
b = [0; 0; 0; 2; 0; 0; 0; 0; 0; 3; 0]
nearestfun = @(b) interp1(find(b),b(b~=0),(1:length(b))','nearest','extrap');
closest = 0.5*(nearestfun(b) + flip(nearestfun(flip(b))))
2 件のコメント
Bruno Luong
2018 年 11 月 2 日
A variant
b = [0; 0; 0; 2; 0; 0; 0; 0; 0; 3; 0]
nearestfun = @(b) interp1(find(b),b(b~=0),(1:length(b))','nearest','extrap');
closest = median([nearestfun(b),flip(nearestfun(flip(b)))],2)
michael fechter
2022 年 12 月 1 日
Just had a similar problem of a frequency logger, skipping a few entries when an infinite value is recorded. works fine for what I was about to do hard coding.
Thanks!
その他の回答 (2 件)
the cyclist
2018 年 11 月 1 日
編集済み: the cyclist
2018 年 11 月 1 日
Assuming my comment above is correct, then here is a somewhat ugly solution:
b = [0 0 0 2 0 0 0 0 0 3 0]';
nonZeroIdx = find(b);
b2 = interp1(nonZeroIdx,b(nonZeroIdx),1:numel(b),'nearest','extrap');
for ni = 1:numel(nonZeroIdx)-1
isOddIdx = mod(nonZeroIdx([ni ni+1]),2);
if not(xor(isOddIdx(1),isOddIdx(2)))
b2(round((nonZeroIdx(ni)+nonZeroIdx(ni+1))/2)) = (b(nonZeroIdx(ni))+b(nonZeroIdx(ni+1)))/2;
end
end
The first part is easy ... using nearest-neighbor interpolation will get most of the values correct.
But you need the for loop (I think) to get the elements that are halfway between non-zero values, and that is ugly. There might be a better way.
2 件のコメント
Guillaume
2018 年 11 月 1 日
Wouldn't it make more sense to perform a linear interpolation and then round to the nearest 0.5? Granted you may get several consecutive values at 0.5 instead of just the middle one but wouldn't that be more appropriate?
the cyclist
2018 年 11 月 1 日
編集済み: the cyclist
2018 年 11 月 1 日
Here is a slightly slicker way:
b = [0 0 0 2 0 0 0 0 0 3 0]';
nonZeroIdx = find(b);
b_extended = [b(nonZeroIdx(1)); b; b(nonZeroIdx(end))];
nonZeroIdx = [1; nonZeroIdx+1; numel(b_extended)];
b_lo = interp1(nonZeroIdx,b_extended(nonZeroIdx),1:numel(b_extended)-1,'nearest','extrap');
b_hi = interp1(nonZeroIdx,b_extended(nonZeroIdx),2:numel(b_extended), 'nearest','extrap');
out = (b_lo+b_hi)/2;
out = out(1:end-1);
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Special Characters についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!