Select first n nonzero elements in each row of matrix
조회 수: 25 (최근 30일)
이전 댓글 표시
Hello
How to select first n nonzero elements from each row?
If I have matrix A, and I want result like B (three nonzero elements from each row):
Rusult also can be cell..
A=[1 3 0 2 5
0 2 0 1 0
2 0 0 0 0
3 1 1 0 0];
B=[1 3 2
2 1 0
2 0 0
3 1 1];
댓글 수: 0
채택된 답변
Stephen23
2020년 6월 24일
편집: Stephen23
2020년 6월 24일
Linear indexing does this simply and efficiently. The trick is to work down the columns, which requires transposing:
>> A = [1,3,0,2,5;0,2,0,1,0;2,0,0,0,0;3,1,1,0,0]
A =
1 3 0 2 5
0 2 0 1 0
2 0 0 0 0
3 1 1 0 0
>> N = 3;
>> Z = A.';
>> S = size(Z);
>> [~,R] = sort(Z==0,1);
>> [~,C] = ndgrid(1:N,1:S(2));
>> X = sub2ind(S,R(1:N,:),C);
>> B = Z(X).'
B =
1 3 2
2 1 0
2 0 0
3 1 1
Probably the most efficient approach would be to use a simple loop, e.g. (not particularly optimized):
R = size(A,1);
B = zeros(R,N);
for k = 1:R
tmp = nonzeros(A(k,:));
idx = 1:min(N,numel(tmp));
B(k,idx) = tmp(idx);
end
Some timings (1e3 iterations):
Elapsed time is 5.358 seconds. % madhan ravi's with loop and CELLFUN
Elapsed time is 0.606 seconds. % my answer with SUB2IND
Elapsed time is 0.265 seconds. % my answer with loop and indexing
추가 답변 (1개)
madhan ravi
2020년 6월 23일
편집: madhan ravi
2020년 6월 23일
ix = cumprod(A ~= 0, 2);
B = A(:, max(ix) ~= 0)
%OR
ix = cumprod(A ~= 0, 2); % remove cumprod(...) if you don't expect n consecutive nonzero elements
n = 3;
idx = find(cumsum(ix,2) == n, 1);
[~, c] = ind2sub(size(A), idx);
B = A(:, 1:c)
% OR
% if you don't want to specify n by yourself
ix = cumprod(A ~= 0, 2); % remove cumprod(...) if you don't expect n consecutive nonzero elements
ix1 = cumsum(ix,2);
idx = find(ix1 == max(max(ix1)), 1); % use max(..., [], 'all') for later versions
[~, c] = ind2sub(size(A), idx);
B = A(:, 1:c)
댓글 수: 3
madhan ravi
2020년 6월 23일
편집: madhan ravi
2020년 6월 23일
n = 3; % n non-zero elements
B = cell(size(A,1),1);
for k = 1:size(A,1)
B{k} = nonzeros(A(k,:)).';
end
B = cellfun(@(x) x(1:numel(x) < n+1), B, 'un', 0);
B = cell2mat(cellfun(@(x) [x, zeros(1, n-numel(x))], B, 'un',0))
참고 항목
카테고리
Help Center 및 File Exchange에서 Graphics Object Programming에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!