我有一個非常大的陣列,有五個通道和約600萬個條目(5 x 6000000)。我的目標是通過7點窗口掃過陣列,並去除「尖峯」,其定義爲比中值絕對偏差(MAD)大一些的縮放量。MATLAB:尋找更快/更優雅的方式來計算很長時間系列的移動中值絕對偏差
我正在測試代碼,只運行10000個時間序列的初始點。目前,我需要大約3秒才能運行前10000個點。我正在運行一臺相對較舊的帶有2.30 GHz處理器和4 GB RAM的32位戴爾筆記本電腦。很明顯,如果我使用的是新電腦,我可以很快完成任務。例如,我的功能更強大的桌面可以在0.7秒內完成相同的任務。但是,我需要在筆記本電腦上運行代碼,每次需要運行代碼時都不能等待35-40分鐘。我正在尋找幫助找到效率低下的地方,以及可以讓代碼更快的地方。
以下是代碼。有關如何提高速度的任何建議表示讚賞。我注意到,「MAD」的計算是最耗時的(需要大約1.9秒,或者超過總時間的一半)。
load('data.mat') % data (approx 5 channels x 6000000 data points (int32))
nscans = length(data); %number of data points in each channel
nwide = 7; %number of data points in the window
% Rejection parameters (not so important for the question)
iscale = 50; %scale factor for MAD
minmad = 2;
mincrit = [100 100 100 500 500];
nfixed=zeros(1,5);
L = floor(nwide/2); %half of window (odd window length only)
%Padding for beginning and end of data
data = [repmat(data(:,1),[1 L]) data repmat(data(:,end),[1 L])];
nfixed = zeros(1,5); %initialize counter
tic
for n = L+1:10000
idata = data(:,n-L:n+L)'; % temporary window
% compute median of window
med=median(idata);
%compute median absolute deviation (MAD)
% Note: mad = median(abs(X - median(X)))
mad = median(abs(idata-repmat(median(idata),[nwide 1])));
mad = max([mad;minmad*ones(1,5)]); %minmad threshold added
%compute rejection threshold
icrit=max([iscale*mad;mincrit]);
for i = 1:5 %loop over channels
if abs(data(i,n)-med(i)) > icrit(i) %if threshold is exceeded
data(i,n)=med(i); %then replace with median value
nfixed(i)=nfixed(i)+1; %count number of replacements
end
end
end
toc
data = data(:,L+1:end-L)'; %remove padding
我覺得有可能是一個更優雅的方式來執行「repmat」命令。
任何想法表示讚賞。
乾杯
當你刪除一個尖峯,這是否會影響未來的Windows計算?它看起來很像你的代碼。這就是這種情況,很難避免一個循環 –
我必須更多地思考這個問題,但第一件事就是你可以做'array-scalar'而不必重新編寫它。這可能會爲你節省一些時間。 – Durkee