【问题标题】:To get sum values of other columns based on first column values根据第一列值获取其他列的总和值
【发布时间】:2014-12-10 04:11:03
【问题描述】:

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

不胜感激。

【问题讨论】:

    标签: matlab


    【解决方案1】:

    更新:最终更快的解决方案!


    可以如下实现,每列一行:

    % 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));
    

    【讨论】:

    • 非常感谢@thewaywewalk !!...非常感谢您提供其他选择
    • @shawpnik:请看一下我的编辑,我发布了另一个解决方案,它更符合您的需求,而且比订单更快!
    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2016-11-30
    相关资源
    最近更新 更多