How to sum data

8 次查看(过去 30 天)
Gimpy
Gimpy 2014-8-5
Hi, my data has the following format:
raw_headers={'D' 'A' 'D' 'B' 'D' 'D'}
raw_data=[5 1 10 1 15 20]
And and want final results that way:
format_headers={'A' 'B' 'C' 'D' }'
format_data=[1;1;0;50]
I have issue doing the summation wihtout a loop for all unique headers.
Any idea?

回答(4 个)

Geoff Hayes
Geoff Hayes 2014-8-5
Since your raw_headers does not necessarily contain all headers (in this case, C is missing) then you could try the following where you define the full list of (unique) headers ahead of time, and iterate over that list
headerData = {'A','B','C','D'};
numChars = length(headerData);
format_data = zeros(numChars,1);
at = 1;
for k=headerData
idcs = find(strcmpi(raw_headers(:),k));
if ~isempty(idcs)
format_data(at) = sum(raw_data(idcs));
end
at = at + 1;
end
So we just iterate over each possible header and grab the indices of each raw header that matches it. Then just sum the raw data given that set of indices. Try the above and see what happens!
  2 个评论
Gimpy
Gimpy 2014-8-5
I was looking for something without a loop
Image Analyst
Image Analyst 2014-8-5
Don't be afraid of a loop so tiny. I mean, it's not like you have tens of millions of these cells, do you? Anyway, I don't see how you're getting the output from the input. Maybe the letter headers are just going from min 'A' to max 'D', but what about the numbers? Is it a histogram?

请先登录,再进行评论。


dpb
dpb 2014-8-5
Easiest will be to augment the header row w/ all values wanted. If do so, then
>> raw_headers={'D' 'A' 'D' 'B' 'D' 'D' 'C'};
>> [~,~,ib]=unique(raw_headers)
ib =
4 1 4 2 4 4 3
>> accumarray(ib.',[raw_data zeros(length(ib)-length(raw_data),1)])
ans =
1
1
0
50
>>
  2 个评论
Gimpy
Gimpy 2014-8-5
Error using accumarray Second input VAL must be a vector with one element for each row in SUBS, or a scalar.
dpb
dpb 2014-8-5
编辑:dpb 2014-8-5
Didn't do something correctly, as you can see I pasted the results directly from the command line.
That error would be true if you used your original data array with the augmented headers. That's the point of the added zeros in the above; to augment to the same length.
Just to be sure, here it is again...
>> raw_headers={'D' 'A' 'D' 'B' 'D' 'D' 'C' };
>> [~,~,ib]=unique(raw_headers)
ib =
4 1 4 2 4 4 3
>> accumarray(ib.',[raw_data zeros(length(ib)-length(raw_data),1)])
ans =
1
1
0
50
>>
Just fine, as advertised. Now don't augment the data array...
>> accumarray(ib.',raw_data)
Error using accumarray
Second input VAL must be a vector with one element for each row in SUBS, or a scalar.
>>
And, yes, Virginia, if you don't add entries for the additional headings, "Houston, we have a problem!"
Ergo, the augmentation is important.
Show your work.

请先登录,再进行评论。


Nade Sritanyaratana
As dpb suggested, you may want to consider using accumarray .
The following code uses raw_headers to index subscripts for accumarray, creates a secondary subscript based on all characters between the minimum (e.g., A) to the maximum (e.g. D), grabs only the values of accumarray that correspond to the secondary subscript, and then reformats the data to the desired output:
raw_headers={'D' 'A' 'D' 'B' 'D' 'D'};
raw_data=[5 1 10 1 15 20];
% Create a numerical subscript of the characters
subs = double(cell2mat(raw_headers'));
% Keep track not just of A, B, and D, but also C, by creating a secondary subscript
subs2 = min(subs):max(subs);
% Sum up arrays according to matching subs (corresponding to matching chars)
A = accumarray(subs,raw_data',[],[]);
% Grab only the sums from A to D
A = A(subs2);
% reformat outputs
format_headers = cellstr(char(subs2)')';
format_data = A';

Andrei Bobrov
Andrei Bobrov 2014-8-5
编辑:Andrei Bobrov 2014-8-5
s = unique(raw_headers);
format_headers = cellstr((s{1}:s{end})');
[~,ii] = ismember(raw_headers,format_headers);
format_data = accumarray(ii(:),raw_data(:));

类别

Help CenterFile Exchange 中查找有关 Dynamic System Models 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by