Tricky matrix conversion question
1 次查看(过去 30 天)
显示 更早的评论
Hey all,
I am trying to convert a matrix A into a new matrix B, by looking at each element in matrix A and whenever the next element (in a row) is different, make a pair and add it to the new matrix B. Also elements with number 0 should be ignored.
As an example: Suppose we have a matrix A, and we want the resulted matrix B.
A = [1 1 1 3 5 B = [1 3
2 2 0 4 5 3 5
2 2 0 0 5] 2 4
4 5
2 5]
This problem could be solved by using a for-loop over all elements in the matrix, however for computational time reasons i am looking for a faster way to convert this, any ideas are welcome :D
0 个评论
采纳的回答
Guillaume
2018-8-7
Actually, it can be done fairly easily without a loop. Whether or not it's faster than Adam's loop, I haven't tested.
A = [1 1 1 3 5;2 2 0 4 5; 2 2 0 0 5];
rows = repmat(1:size(A, 1), size(A, 2), 1);
At = A';
mask = At ~= 0;
Anz = At(mask);
pair1 = diff(Anz) ~= 0 & ~diff(rows(mask));
B = [Anz(pair1), Anz([false; pair1])]
1 个评论
更多回答(1 个)
Adam Danz
2018-8-7
编辑:Adam Danz
2018-8-7
Sure, it's probably possible to avoid a loop entirely. But that doesn't mean it's practical.
This proposal loops through rows of A, removes 0s, differentiates to find changes, then extracts pairs and stores them in B to produce your desired results.
B = [];
% Loop over rows of A
for i = 1:size(A,1)
% remove 0s
tempRow = A(i,A(i,:)~=0);
% differentiate
d = diff(tempRow);
% Extract non=0 pairs
pairedIdx = find(d~=0);
% Detect pairs that differ and store in B
pairedNums = [tempRow(pairedIdx)', tempRow(pairedIdx+1)'];
B(end + 1 : end + size(pairedNums,1),:) = pairedNums;
end
In fact, when I change A to
A = randi(10, 1000, 1000)-1;
which contains 1 million elements in 1000 rows, it only takes ~1 sec using tic/toc.
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!