2014-03-01 57 views
1

我有多個excel文件,如下所示(小時數據)。我想獲得日常的平均值(例如,從第二天的17:00到16:00)。我只知道一點Matlab。目前我的解決方案在下面,但它有一些問題。使用MATLAB的多個excel文件中的平均數據

  1. 讀取每個excel文件並將數據存儲在變量中。
  2. 合併單個變量中的所有數據。
  3. 17:00查找行號(n)。爲此,我獲得了每行的日期數據,然後只搜索(查找)對應於17:00的日期數據。
  4. 平均每兩行之間的數據(n(i))。

如果原始數據是正確的,它工作正常。但是問題在下面。

  1. 17:00的一些數據丟失。所以當它試圖在17:00找到該行時會出現錯誤。
  2. 當我有超過100個excel文件時,它運行非常慢。

可以有人提出一些建議如何解決這個問題嗎?我更喜歡使用Matlab,因爲它是我知道的唯一工具。非常感謝!

編輯1:代碼提供

下面是代碼以獲得平均每天。我已經結合在文件「summary_file.xls」中的所有數據中未示出(該部分的代碼。

作爲例子表如下所示。

  1. 平均爲17:00之間的時間,9月1日和9月2日沒有問題。
  2. 對於有數據缺失的日子,我想要在17:00之前獲得所有可用數據的平均值
  3. 例如:因爲17:00的數據3 9月失蹤,無法獲得9月2 - 3日的平均值。對於這種情況,我想在17:00之前獲得所有數據的平均值(即9月3日9:00之前)
  4. 然後9月3-4日,我想從18:00開始計算平均值。
  5. 對於所有數據缺失的日子,只需將所有數據設爲0或標記爲不可用。

[num,txt,raw] = xlsread('summary_file.xls'); %讀取文件

date_num = num(:,11); % read the column containing date number 
starting = '2003/09/05-17:00'; % starting time 
starting = datenum(starting,formatIn_2); % convert starting time to date number 
ending = '2003/09/09-17:00';% ending time 
ending = datenum(ending,formatIn_2); %convert ending time to date number 

s = starting:1:ending; % All date number with 17:00 

%% find the row number with 17:00 
for i = 1:ending-starting+1 
    [a(i) b(i)] = find(date_num==s(i)); 
end 
%% Store the averaged data in variable p 
for i = 1:ending-starting 
    p(i,:) = mean(num(a(i):a(i+1)-1,:)); 
end 

取樣輸入數據 -

 
+------+-------+----------+-------+-------+-------+-------+-------+-------+ 
| 2003 | 1-Sep | 15:00 | 100.2 | 29 | 70.5 | 3.903 | 728 | 0 | 
+------+-------+----------+-------+-------+-------+-------+-------+-------+ 
| 2003 | 1-Sep | 16:00 | 100.1 | 29.31 | 70.7 | 4.328 | 611.8 | 0  | 
| 2003 | 1-Sep | 17:00 | 100.1 | 29.64 | 67.06 | 3.719 | 434.8 | 0  | 
| 2003 | 1-Sep | 18:00 | 100.1 | 29.67 | 64.4 | 3.005 | 172.4 | 0  | 
| 2003 | 1-Sep | 19:00 | 100.1 | 29.06 | 68.22 | 2.292 | 19.89 | 0  | 
| 2003 | 1-Sep | 20:00 | 100.2 | 28.43 | 74.7 | 2.436 | 0.428 | 0  | 
| 2003 | 1-Sep | 21:00 | 100.2 | 27.92 | 76.2 | 1.931 | 0.006 | 0  | 
| 2003 | 1-Sep | 22:00 | 100.3 | 27.67 | 77.3 | 1.825 | 0.007 | 0  | 
| 2003 | 1-Sep | 23:00 | 100.4 | 27.55 | 77.9 | 1.622 | 0.007 | 0  | 
| 2003 | 1-Sep | 24:00:00 | 100.4 | 27.69 | 77.8 | 0.863 | 0.008 | 0  | 
| 2003 | 2-Sep | 1:00  | 100.4 | 27.55 | 78.3 | 0.879 | 0.008 | 0  | 
| 2003 | 2-Sep | 2:00  | 100.3 | 27.05 | 82.1 | 1  | 0.016 | 0.762 | 
| 2003 | 2-Sep | 3:00  | 100.3 | 26.41 | 86.8 | 0.805 | 0.006 | 0  | 
| 2003 | 2-Sep | 4:00  | 100.2 | 26.6 | 85.5 | 0.522 | 0.011 | 0.508 | 
| 2003 | 2-Sep | 5:00  | 100.2 | 25.53 | 83.8 | 2.158 | 0.011 | 0  | 
| 2003 | 2-Sep | 6:00  | 100.3 | 24.5 | 86.6 | 2.711 | 0.016 | 0  | 
| 2003 | 2-Sep | 7:00  | 100.4 | 24.85 | 86.9 | 2.562 | 0.016 | 4.318 | 
| 2003 | 2-Sep | 8:00  | 100.6 | 21.11 | 94 | 8.15 | 9.96 | 26.67 | 
| 2003 | 2-Sep | 9:00  | 100.6 | 22.23 | 91.9 | 5.065 | 31.67 | 0.254 | 
| 2003 | 2-Sep | 10:00 | 100.6 | 23.51 | 88.8 | 5.742 | 39.16 | 0.254 | 
| 2003 | 2-Sep | 11:00 | 100.6 | 24 | 87.7 | 4.494 | 97.8 | 0  | 
| 2003 | 2-Sep | 12:00 | 100.6 | 24.69 | 85.3 | 4.709 | 142.2 | 0  | 
| 2003 | 2-Sep | 13:00 | 100.5 | 25.57 | 82.8 | 5.66 | 259.1 | 0  | 
| 2003 | 2-Sep | 14:00 | 100.4 | 25.69 | 81.9 | 5.634 | 157.5 | 0  | 
| 2003 | 2-Sep | 15:00 | 100.3 | 26.18 | 79.1 | 5.564 | 308.2 | 0  | 
| 2003 | 2-Sep | 16:00 | 100.3 | 26.08 | 78.3 | 6.283 | 135.3 | 0  | 
| 2003 | 2-Sep | 17:00 | 100.3 | 25.75 | 81.2 | 4.595 | 55.68 | 0.762 | 
| 2003 | 2-Sep | 18:00 | 100.3 | 25.01 | 84.5 | 4.843 | 55.21 | 1.778 | 
| 2003 | 2-Sep | 19:00 | 100.3 | 25.15 | 86.1 | 1.433 | 22.43 | 0  | 
| 2003 | 2-Sep | 20:00 | 100.3 | 24.98 | 86.1 | 1.985 | 0.301 | 0  | 
| 2003 | 2-Sep | 21:00 | 100.3 | 24.75 | 85.1 | 0.712 | 0.009 | 0  | 
| 2003 | 2-Sep | 22:00 | 100.4 | 24.76 | 85.3 | 1.546 | 0.011 | 0  | 
| 2003 | 2-Sep | 23:00 | 100.5 | 24.92 | 84.5 | 1.186 | 0.008 | 0  | 
| 2003 | 2-Sep | 24:00:00 | 100.5 | 24.96 | 84.9 | 1.31 | 0.007 | 0  | 
| 2003 | 3-Sep | 1:00  | 100.5 | 25 | 85.3 | 0.702 | 0.012 | 0  | 
| 2003 | 3-Sep | 2:00  | 100.5 | 24.99 | 86 | 0.35 | 0.017 | 0  | 
| 2003 | 3-Sep | 3:00  | 100.4 | 25.07 | 86.1 | 0.69 | 0.008 | 0  | 
| 2003 | 3-Sep | 4:00  | 100.3 | 24.92 | 86.5 | 1.347 | 0.011 | 0  | 
| 2003 | 3-Sep | 5:00  | 100.3 | 25.27 | 85.5 | 0.834 | 0.009 | 0  | 
| 2003 | 3-Sep | 6:00  | 100.3 | 24.97 | 86.9 | 0.627 | 0.012 | 0  | 
| 2003 | 3-Sep | 7:00  | 100.3 | 24.8 | 87.7 | 0.755 | 0.108 | 0  | 
| 2003 | 3-Sep | 8:00  | 100.4 | 25.54 | 85 | 0.202 | 37.11 | 0  | 
| 2003 | 3-Sep | 9:00  | 100.4 | 26.72 | 81 | 1.853 | 219.4 | 0  | 
| 2003 | 3-Sep | 18:00 | 100.2 | 29.67 | 56.39 | 2.856 | 456.2 | 0  | 
| 2003 | 3-Sep | 19:00 | 100.2 | 30.17 | 53.66 | 2.204 | 266 | 0  | 
+------+-------+----------+-------+-------+-------+-------+-------+-------+ 

回答

1

下面的代碼可能會滿足您的要求。再一次,因爲你對日常平均數感興趣,所以輸出將會更小,因爲它已經超過了24小時,我假設你需要這個。此外,它還會處理您缺少的數據條件。

碼 -

%% Setup params and data 
start_hour = 17; 
[num,txt,raw] = xlsread('summary_file.xls'); 

datenums = NaN(size(num,1),1); 
for count = 1:size(num,1) 
    year1 = cell2mat(raw(count,1)); 
    date1 = cell2mat(raw(count,2)); 
    time1 = cell2mat(raw(count,3)); 
    date_str = strcat(num2str(year1) , '-', date1); 
    datenums(count) = datenum(date_str, 'yyyy-dd-mmm') + time1(:); 
end 

%% Take care of conditions 
firstdata_start_hour = round(24*cell2mat(raw(1,3))); 
if firstdata_start_hour > 17 
    start1 = floor(datenums(1)) + (start_hour/24); 
elseif firstdata_start_hour < 17 
    start1 = floor(datenums(1))-1 + (start_hour/24); 
else 
    start1 = datenums(1); 
end 

ind1 = floor(datenums-start1) + 1; 

%% Start Processing 
num_items = size(num,2)-3; 
num_days = max(ind1); 

bins = NaN(num_days,num_items); 
for count1 = 1:size(bins,2) 
    for count2 = 1:size(bins,1) 
     bins(count2,count1) = mean(num(find(ind1==count2),count1+3)); 
    end 
end 
bins(isnan(bins))=0; 
average_nums = bins 

對一些數據的平均值的輸出,通過OP對我的要求編制 -

+-----------+---------------+------+-------------+------------+-----------+--------------+ 
| Date | Pressure(kPa) | Temp | Humidity(%) | W-spd(m/s) | Radiation | Rainfall(mm) | 
+-----------+---------------+------+-------------+------------+-----------+--------------+ 
| 8/10/2009 | 100.1   | 25.8 | 79.1  | 1.4  | 82.6  | 1.7   | 
| 8/11/2009 | 100.2   | 27.5 | 75.7  | 1.9  | 173.8  | 0.0   | 
| 8/12/2009 | 100.1   | 28.4 | 73.5  | 2.1  | 177.1  | 0.0   | 
| 8/13/2009 | 100.0   | 28.4 | 73.2  | 2.5  | 197.4  | 0.0   | 
| 8/14/2009 | 100.0   | 28.5 | 73.5  | 2.2  | 151.2  | 0.0   | 
| 8/15/2009 | 100.2   | 27.3 | 75.4  | 1.2  | 96.2  | 0.4   | 
| 8/16/2009 | 100.2   | 27.1 | 75.5  | 1.4  | 122.6  | 0.0   | 
| 8/17/2009 | 100.2   | 27.2 | 75.7  | 1.5  | 158.3  | 0.2   | 
| 8/18/2009 | 100.2   | 27.5 | 72.2  | 1.4  | 186.4  | 0.0   | 
| 8/19/2009 | 100.3   | 28.4 | 68.4  | 1.9  | 186.9  | 0.0   | 
| 8/20/2009 | 100.3   | 28.1 | 69.2  | 2.0  | 184.8  | 0.0   | 
| 8/21/2009 | 100.3   | 26.5 | 75.8  | 1.3  | 122.3  | 0.6   | 
+-----------+---------------+------+-------------+------------+-----------+--------------+ 

對於多個Excel文件,你必須循環遍歷所有這些文件循環。似乎沒有任何其他出路。

+0

非常感謝!上面的代碼很好用!但是第9行中的'time1(:)'需要修改爲'time1(:)/ 24'。這是對的嗎? – user2230101

+0

讀入time1 - 「time1 = cell2mat(raw(count,3));」後,檢查time1的值。如果他們是分數,不要用24除法,否則使用它。在我的系統中,它讀取的是分數,所以我不需要24分頻。我懷疑這可能是您創建XLS表或MATLAB版本本身的方式的問題。 – Divakar

+0

考慮投票回答有用的答案。這不僅可以用於接受的答案,也可以用於其他人。在這裏閱讀更多 - http://stackoverflow.com/help/privileges/vote-up – Divakar

0

當您使用Matlab的xlsread它打開和關閉Excel的COM服務器,因此採用這種使用多個文件會減慢執行。在Matlab Central閱讀this post,它解釋瞭如何避免打開和關閉Excel COM Server。

至於丟失的數據,也許你可以插值17:00從find(time<17:00,'last')數據和find(time>17:00,'first')

+0

謝謝!對於xlasread,我會閱讀你推薦的帖子。對於缺少的數據,我在問題中添加了更多信息(編輯1),您可以幫助查看一下嗎? – user2230101

+0

我認爲它不會使用com服務器,如果你可以堅持'basic'模式。 –

0

我喜歡使用MATLAB,但如果你不介意我問,你有沒有考慮使用R統計軟件包?在我看來,它非常酷,你不必同意我的看法。

這是很容易做你所要求的任務。 R甚至可以處理缺失的數據並輕鬆解決它,並可以輕鬆讀取excel文件並搜索您想要的數據。

哪裏可以得到R:

http://cran.r-project.org/

+0

謝謝!我也對使用R感興趣。但是我沒有足夠的時間爲此任務學習新軟件。可能以後我可以拿起它。 – user2230101