Better way to pull out values from a struct

조회 수: 2 (최근 30일)
Sam Litvin
Sam Litvin 2020년 1월 18일
댓글: Walter Roberson 2020년 1월 18일
I have a matrix with a matrix CT of struct data called callsTable. I'm trying to pull out just one of the columns called Time and create a 1D vector using the following code. Is there a better way that I can do this? Currently, running the code I get the following error message.
Unable to perform assignment because the size of the left side is 28-by-1 and the size of the right side is
6-by-1.
for k=1:size(CT,1)
for i=size(CT(k),1)
T(:,i)=CT(k).callsTable.Time
end
end

답변 (3개)

Walter Roberson
Walter Roberson 2020년 1월 18일
Times = arrayfun(@(S) S.callsTable.Time, CT, 'uniform', 0);
T = horzcat(Times{:});
The assignment to T will fail if the Time vectors were not all the same size.

Sam Litvin
Sam Litvin 2020년 1월 18일
Thanks Walter
I tried that, got this: Error using horzcat, Dimensions of arrays being concatenated are not consistent.
So then I tried vertcat instead, but got same issue as before. I am preallocatin the matrix by scanning the CT to find the max number there and creating a matrix of zeros
for n=1:size(CT,1)
call_tot=size(CT(n).callsTable.Time);
calls(n,:)=call_tot;
end
tablsize=size(CT,1);
maxcalls=max(calls);
T=zeros(maxcalls(1),tablsize);
  댓글 수: 2
Walter Roberson
Walter Roberson 2020년 1월 18일
time_lengths = arrayfun(@(S) length(S.callsTable.Time), CT);
max_time_lengths = max(time_lengths);
FirstN = @(V, N) V(1:N);
PadN = @(V, N) FirstN([V; zeros(N,1)]);
Times = arrayfun(@(S) PadN(S.callsTable.Time, max_time_lengths), CT, 'uniform', 0);
T = horzcat(Times{:});
Walter Roberson
Walter Roberson 2020년 1월 18일
time_lengths = arrayfun(@(S) length(S.callsTable.Time), CT);
max_time_lengths = max(time_lengths);
FirstN = @(V, N) V(1:N);
PadN = @(V, N) FirstN([V; zeros(N,1)], N);
Times = arrayfun(@(S) PadN(S.callsTable.Time, max_time_lengths), CT, 'uniform', 0);
T = horzcat(Times{:});

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


Sam Litvin
Sam Litvin 2020년 1월 18일
Thanks Walter, I really appreciate it.
Interesting method, I like it. Could you please explain what you're doing here:
FirstN = @(V, N) V(1:N);
PadN = @(V, N) FirstN([V; zeros(N,1)]);
because I get this error and I'm not sure how to debug
Not enough input arguments.
Error in Euler_GLM>@(V,N)V(1:N) (line 20)
FirstN = @(V, N) V(1:N)
Error in Euler_GLM>@(V,N)FirstN([V;zeros(N,1)]) (line 21)
PadN = @(V, N) FirstN([V; zeros(N,1)]);
Error in Euler_GLM>@(S)PadN(S.callsTable.Time,max_time_lengths) (line 22)
Times = arrayfun(@(S) PadN(S.callsTable.Time, max_time_lengths), CT, 'uniform', 0);
  댓글 수: 1
Walter Roberson
Walter Roberson 2020년 1월 18일
FirstN: takes the first N elements of whatever is handed in
PadN : take whatever input is given and always add N zeros at the end of it, and then call FirstN to pull out the first N of whatever that ends up being
So for example, PadN([1;2;3], 7) would form [1;2;3;0;0;0;0;0;0;0] and then ask FirstN to take the first 7 of those, getting out [1;2;3;0;0;0;0] as the result.
There are other ways of constructing something like this, including
PadN = @(V, N) [V; zeros(N-length(V), 1)]
which does not require as many steps.

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

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by