Convert cell array of structures to numeric vector

조회 수: 5 (최근 30일)
Alessandro
Alessandro 2024년 10월 3일
댓글: Voss 2024년 10월 3일
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!

채택된 답변

Yukthi S
Yukthi S 2024년 10월 3일
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
Voss
Voss 2024년 10월 3일
@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

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Voss
Voss 2024년 10월 3일
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
Voss
Voss 2024년 10월 3일
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>

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Structures에 대해 자세히 알아보기

제품


릴리스

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by