excel文件包含5列;第一列包含年份(1987年至2080年),第二列包含月份,第三列包含日期,第四列和第五列包含值。我希望在第一列中根据年份得到第四列和第五列的总和值。例如,我想获得1987年,1988年,1989年......等等的第四和第五列的总和值。 Example of data file is attached
考虑到每年包含365天,我尝试了以下代码。
n=1;
for i=1:365:size(data,1)
Total(n,:) = sum(data(i:i+365-1,:));
n=n+1;
end
但问题是并非所有年份都包含365天。其中一些(例如1988年,1992年)一年中有366天,因为它们是闰年。在这些情况下,总和结果变得不正确。
寻求帮助,根据第1列中的年份获得第4列和第5列的总和值。
非常感谢。
答案 0 :(得分:3)
更新:最后更快的解决方案!
可以按如下方式进行,每列一行:
% some example data
years = ceil(1987:0.3:2080)';
months = randi(12,numel(years),1);
days = randi(30,numel(years),1);
values = randi(42,numel(years),2);
% data similar to yours;
data = [ years months days values ];
这将是简单易读的方式:
% years
y = data(:,1)
% unique years
uy = unique(y);
% for column 4
C4 = arrayfun(@(x) sum( data(y == x, 4) ), uy )
% for column 5
C5 = arrayfun(@(x) sum( data(y == x, 5) ), uy )
或每列短一行:
C4 = arrayfun(@(x) sum( data( (data(:,1) == x), 4) ), unique(data(:,1)) )
返回一个94x1
双数组,其中包含示例数据的所有94个唯一年份的所有总和。
如果你想以某种方式安排它,你可以这样做:
summary = [uy, C4, C5]
返回类似的内容:
summary = %//sum of sum of
column 4 column 5
1987 3 3
1988 40 40
1989 56 56
1990 96 96
1991 54 54
1992 15 15
1993 73 73
1994 42 42
1995 66 66
1996 56 56
...
您也可以一次完成所有列。已经只有2列,它应该快50%。
cols = 4:5;
C = cell2mat( arrayfun(@(x) sum( data(y == x, cols),1 ), uy,'uni',0 ) )
该解决方案的问题在于,您有一个大约30000x5
大小的矩阵,并且对于每个唯一年份,它将对整个矩阵应用索引以“搜索”当前年份,这是总结的。但实际上有一个内置函数正是这样做的:
您可以使用 accumarray
实现更简单,更快捷的解决方案:
[~,~, i_uy] = unique(data(:,1));
C4 = accumarray(i_uy,data(:,4));
C5 = accumarray(i_uy,data(:,5));