Filter löschen
Filter löschen

Assigning array values to cell array based on condition

11 Ansichten (letzte 30 Tage)
Dominik Rhiem
Dominik Rhiem am 13 Dez. 2021
Kommentiert: Dominik Rhiem am 21 Dez. 2021
I have two equally-sized vectors of indices like the following:
A = [1, 1, 1, 2, 2, 3, 3, 3, 3];
B = [6, 3, 7, 4, 7, 13, 16, 4, 1];
I want to assign the values of B into cell arrays based on the value of A at the same index, i.e.:
C{1} = B(A==1);
C{2} = B(A==2);
C{3} = B(A==3);
In reality, A contains all integers from 1 to 1600 (monotonically increasing, but each integer appears a different number of times), so it is impractical to write all lines out. So far, I have solved this with a loop (in each iteration, I create the mask C = B(A==iteration)), but loops are inefficient, so are there better ways to do it?
Similarly, I want to use this to assign values to the elements of a vector v. For example:
v(1) = sum(M(C{1}));
v(2) = sum(M(C{2}));
Where M is some other large vector from which we select the relevant entries by the indices in C as indicated. Again, this is currently implemented as a loop (i.e. v(i) = sum(M(B(A==i))) ), which works, but again, are there better ways to do it?

Akzeptierte Antwort

Stephen23
Stephen23 am 13 Dez. 2021
Bearbeitet: Stephen23 am 13 Dez. 2021
A = [1,1,1,2,2,3,3,3,3];
B = [6,3,7,4,7,13,16,4,1];
C = accumarray(A(:),B(:),[],@(v){v});
C{:}
ans = 3×1
6 3 7
ans = 2×1
4 7
ans = 4×1
13 16 4 1
For the second part of your question I would skip the cell array entirely:
M = randi(9,1,20);
V = accumarray(A(:),M(B(:)),[],@sum)
V = 3×1
15 9 17
  2 Kommentare
Dominik Rhiem
Dominik Rhiem am 14 Dez. 2021
Bearbeitet: Dominik Rhiem am 15 Dez. 2021
This is great, thank you. There is still one issue though: In one instance, I want to use accumarray to first take the logarithm of selected elements of a vector and then take the sum of those elements. However, some entries of that vector are 0, meaning after taking the logarithm they are at -Inf (we later take the exponential so that the result is 0 again). This was fine in the 'loop version' because Log would simply return -Inf (meaning after the sum and taking the exponential, we end up with 0 again), however, with accumarray, I get the following error: The function 'log' returned a non-scalar value. How can I solve this issue?
edit: Nevermind, I got it. First took the log of the whole thing and then the sum of the selected elements.
Dominik Rhiem
Dominik Rhiem am 21 Dez. 2021
Hi, if you don't mind, I have a follow-up question. What if M and v are now matrices, not vectors, where I want to do the operation described above column-wise? I.e.:
v(:,1) = accumarray(A(:), v(B(:),1), [], @sum);
v(:,2) = accumarray(A(:), v(B(:),2), [], @sum);
Again, currently, I solved this with a loop, but more efficiency would be nice.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Matrices and Arrays finden Sie in Help Center und File Exchange

Tags

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by