MATLAB:寻找更快/更优雅的方法来计算非常长的时间序列的移动中值绝对偏差

标签 matlab performance median large-data

我有一个非常大的数组,有五个 channel 和大约 600 万个条目 (5 x 6000000)。我的目标是使用 7 点窗口扫描阵列并移除“尖峰”,尖峰被定义为大于中值绝对偏差 (MAD) 的某个缩放量。

我通过仅运行时间序列的 10000 个初始点来测试代码。目前,我运行前 10,000 个点大约需要 3 秒。我在一台相对较旧的 32 位戴尔笔记本电脑上运行,配备 2.30 GHz 处理器和 4 GB 内存。显然,如果我使用较新的计算机,我可以很快完成任务。例如,我的功能更强大的台式机在 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”命令可能有更优雅的方式。

欢迎任何想法。

干杯

最佳答案

Any suggestions for how to improve the speed is appreciated.

您可以通过不重复您的 median(idata) 调用来稍微简化您的代码。

改变这个:

mad = median(abs(idata-repmat(median(idata),[nwide 1])));

为此:

mad = median(abs(idata-repmat(med,[nwide 1])));

或者,您可以从 MATLAB's mad 中获得更多里程函数,它出现在 2006 年之前。不过您需要更改变量名称。

例如,您可以将代码更改为:

mad = median(abs(idata-repmat(median(idata),[nwide 1])));
mad = max([mad;minmad*ones(1,5)]); %minmad threshold added

madV = max(mad(idata);[2 2 2 2 2]);

我只是将 2 的向量放在那里,因为代码中没有任何内容显示正在更新 minmad

关于MATLAB:寻找更快/更优雅的方法来计算非常长的时间序列的移动中值绝对偏差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45224939/

相关文章:

performance - 通过空矩阵乘法初始化数组的更快方法? (Matlab)

Matlab: 'extrinsics'函数中的平移向量

c - 可以从 C 或 Fortran 中读取 .Rdata 文件格式吗?

java - 结合快速排序和中值选择算法

MATLAB:字符串元胞数组的比较

c# - Web.config 生产环境性能 - 最佳实践

mysql - 优化我的自定义 RAND() 查询

r - 如何使用 R 找到 2 列的中位数?

Java,使用Math.random计算中位数和平均值

matlab 计算 0.9<0.9 为 `True`