Convert cell array of structures to numeric vector

4 visualizaciones (últimos 30 días)
Alessandro
Alessandro el 3 de Oct. de 2024
Comentada: Voss el 3 de Oct. de 2024
Suppose I have
ale{1}.a = 0;
ale{2}.a = 1;
ale{3}.a = 1.5
ale = 1x3 cell array
{1x1 struct} {1x1 struct} {1x1 struct}
ale_vec = NaN(length(ale),1);
for ii=1:length(ale)
ale_vec(ii) = ale{ii}.a;
end
disp(ale_vec)
0 1.0000 1.5000
I would like to generate
%ale_vec = [0,1,1.5]
Is there a quick way to do this without using a loop?
Thanks!

Respuesta aceptada

Yukthi S
Yukthi S el 3 de Oct. de 2024
The function arrayfun can be used to extract the values of the field a from each structure within the cell array ale and store them in a vector called ale_vec without explicitly using a for loop.
ale{1}.a = 0;
ale{2}.a = 1;
ale{3}.a = 1.5;
% Use arrayfun to extract the 'a' field from each element in the cell array
ale_vec = arrayfun(@(x) x.a, [ale{:}]);
% Display the result
disp(ale_vec);
0 1.0000 1.5000
You can find more about arrayfun in the below MathWorks documentation:
  1 comentario
Voss
Voss el 3 de Oct. de 2024
@Alessandro: I thought you wanted to know a quick way without a loop, but the answer you've accepted uses arrayfun, which uses a loop and is slower than the "direct" method I showed, which uses only indexing and concatenation:
N = 7;
ty = zeros(N,1);
tv = zeros(N,1);
M = 10.^(0:N-1).';
for ii = 1:N
ale = num2cell(struct('a',num2cell(rand(1,M(ii)))));
ty(ii) = timeit(@()run_arrayfun(ale));
tv(ii) = timeit(@()run_direct(ale));
end
format long g
T = table(M,ty,tv,'VariableNames',{'# of cells','arrayfun time','direct time'})
T = 7x3 table
# of cells arrayfun time direct time __________ _____________ ____________________ 1 1.16775e-05 4.7871e-06 10 3.92943e-05 1.48168650793651e-05 100 0.0002868775 7.41060714285714e-05 1000 0.0027108175 0.0007648575 10000 0.0277998175 0.0077908175 100000 0.2808028175 0.0920128175 1000000 2.9622488175 0.9987388175
function V = run_arrayfun(C)
V = arrayfun(@(x) x.a, [C{:}]);
end
function V = run_direct(C)
S = [C{:}];
V = [S.a];
end

Iniciar sesión para comentar.

Más respuestas (1)

Voss
Voss el 3 de Oct. de 2024
ale{1}.a = 0;
ale{2}.a = 1;
ale{3}.a = 1.5
ale = 1x3 cell array
{1x1 struct} {1x1 struct} {1x1 struct}
This will work for the given example:
S = [ale{:}];
ale_vec = [S.a]
ale_vec = 1×3
0 1.0000 1.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
  1 comentario
Voss
Voss el 3 de Oct. de 2024
If the structs inside the cells of the cell array have different sets of fields, then they cannot be put together into a single struct array (which is what [ale{:}] does). In that case, you can use cellfun which (like arrayfun) implements a loop:
% cell array containing structs with different field sets
ale{1}.a = 0;
ale{2}.a = 1;
ale{3}.a = 1.5;
ale{3}.b = -2;
ale{:}
ans = struct with fields:
a: 0
ans = struct with fields:
a: 1
ans = struct with fields:
a: 1.5000 b: -2
ale_vec = cellfun(@(s)s.a,ale)
ale_vec = 1×3
0 1.0000 1.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

Iniciar sesión para comentar.

Categorías

Más información sobre Structures en Help Center y File Exchange.

Productos


Versión

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by