2014-03-30 119 views
1

excel文件包含5列;第一列包含年份(1987年至2080年),第二列包含月份,第三列包含日期,第四和第五列包含值。我想在第一欄中得到第四和第五列的總和值。例如,我想得到1987年,然後是1988年,然後是1989年,第4列和第5列的總和值......等等。 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。

回答

2

更新:更快的解決方案在最後!


這是可以做到與每列一行如下:

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

感謝@thewaywewalk !! ...很大感謝您提供其他選項 – shawpnik

+0

@shawpnik:請看看我的編輯,我發佈了另一個解決方案,它更適合您的需求,不僅僅是更快的訂單! – thewaywewalk