Assigning array values to cell array based on condition

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?

 Respuesta aceptada

Stephen23
Stephen23 el 13 de Dic. de 2021
Editada: Stephen23 el 13 de Dic. de 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 comentarios

Dominik Rhiem
Dominik Rhiem el 14 de Dic. de 2021
Editada: Dominik Rhiem el 15 de Dic. de 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.
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.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Productos

Versión

R2021b

Etiquetas

Preguntada:

el 13 de Dic. de 2021

Comentada:

el 21 de Dic. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by