2013-08-04 25 views
1

這的平均值爲後續前面一個問題的礦井發佈here。基於Oleg Komarov的回答,我寫了一個小工具來獲取使用accumarray()和datevec()的輸出結構的數據的每日,每小時等平均值或總和。隨意看看它here(它可能寫得不好,但它適用於我)。MATLAB:N分鐘/小時/天的時間序列

我想什麼,現在做的是添加計算正分鐘,正時,正天等統計數據,而不是1分鐘,1小時,1天等類似的功能我功能確實。我有一個粗略的想法,就是簡單地循環我的時間向量t(如果我沒有了解美麗的準確數據,這將是我已經做的很多事情),但這意味着我必須做很多事情錯誤檢查數據差距,採樣時間不均勻等。

我想知道是否有一種更優雅/高效的方法,可以讓我重新使用/擴展上面發佈的舊功能,即仍然使用準系統的東西()和datevec(),因爲這使得處理差距非常容易。

您可以從我的最後一個問題here採取了一些樣本數據。這些都是以30個分鐘間隔採樣,所以我想這樣做將是一個可能的例子來計算6小時平均沒有依靠假設他們都是免費的空白和/或總是在整整30分鐘取樣的。


這是我想出了到目前爲止,它從一個小而易於固定的問題與時間戳效果相當好,除了(如0:30是從0:30到間隔代表0:45 - 我的老功能從同一問題的困擾,雖然):

[...看到我的回答如下...]

感謝woodchips尋找靈感。

回答

1

我想我想通了使用@Bas Swinckels答案,上面鏈接@woodchip的部分代碼。不完全是我稱之爲良好的代碼,但工作和相當快。

function [ t_acc, x_acc, subs ] = ts_aggregation(t, x, n, target_fmt, fct_handle) 
% t is time in datenum format (i.e. days) 
% x is whatever variable you want to aggregate 
% n is the number of minutes, hours, days 
% target_fmt is 'minute', 'hour' or 'day' 
% fct_handle can be an arbitrary function (e.g. @sum) 
    t = t(:); 
    x = x(:); 
    switch target_fmt 
     case 'day' 
      t_factor = 1; 
     case 'hour' 
      t_factor = 1/24; 
     case 'minute' 
      t_factor = 1/(24 * 60); 
    end 
    t_acc = (t(1) : n * t_factor : t(end))'; 
    subs = ones(length(t), 1); 
    for i = 2:length(t_acc) 
     subs(t > t_acc(i-1) & t <= t_acc(i)) = i; 
    end 
    x_acc = accumarray(subs, x, [], fct_handle); 
end 

/編輯:更新爲使用循環的更短的結構,但似乎比我以前的解決方案更快。

2

如果開始時沒有任何間隙均勻分佈的測量使用accumarray的連接方法似乎矯枉過正,太複雜了我。我在我的私人工具箱中的以下功能爲載體的N點平均值計算:

function y = blockaver(x, n) 
% y = blockaver(x, n) 
% input points are averaged over n points 
% always returns column vector 

if n == 1 
    y = x(:); 
else 
    nblocks = floor(length(x)/n); 
    y = mean(reshape(x(1:n * nblocks), n, nblocks), 1).'; 
end 

工作得很好了N倍快速和骯髒的抽取,但要注意,它不適適當抗混疊過濾。如果這很重要,請使用decimate

+1

感謝您分享您的功能,一定會保存以備後用。它有點接近我的想法,雖然其重塑的使用更優雅一些。但是,你已經提到了自己爲什麼'accumarray'在我的情況下更勝一籌:我使用環境數據,可悲的是,他們很少完成和/或均勻間隔。我應該提到這一點。 –

相關問題