根据第一列值获取其他列的总和值

时间:2014-03-30 00:23:45

标签: matlab

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列的总和值。

非常感谢。

1 个答案:

答案 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));