Effacer les filtres
Effacer les filtres

Tricky matrix conversion question

1 vue (au cours des 30 derniers jours)
Niels de Vries
Niels de Vries le 7 Août 2018
Modifié(e) : Adam Danz le 7 Août 2018
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

Réponse acceptée

Guillaume
Guillaume le 7 Août 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 commentaire
Adam Danz
Adam Danz le 7 Août 2018
Modifié(e) : Adam Danz le 7 Août 2018
Slow clap! (+1)
@Niels de Vries, this version is 10x faster than mine when tested with my 1 million randi() data. Use this one.

Connectez-vous pour commenter.

Plus de réponses (1)

Adam Danz
Adam Danz le 7 Août 2018
Modifié(e) : Adam Danz le 7 Août 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.

Catégories

En savoir plus sur Programming dans Help Center et File Exchange

Produits


Version

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by