Tricky matrix conversion question

1 visualizzazione (ultimi 30 giorni)
Niels de Vries
Niels de Vries il 7 Ago 2018
Modificato: Adam Danz il 7 Ago 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

Risposta accettata

Guillaume
Guillaume il 7 Ago 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 Commento
Adam Danz
Adam Danz il 7 Ago 2018
Modificato: Adam Danz il 7 Ago 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.

Accedi per commentare.

Più risposte (1)

Adam Danz
Adam Danz il 7 Ago 2018
Modificato: Adam Danz il 7 Ago 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.

Prodotti


Release

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by