Tricky matrix conversion question
1 view (last 30 days)
Show older comments
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 Comments
Accepted Answer
Guillaume
on 7 Aug 2018
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 Comment
More Answers (1)
Adam Danz
on 7 Aug 2018
Edited: Adam Danz
on 7 Aug 2018
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 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!