Matlab 科研技巧:将一个数组中连续递增的的元素归类求平均

       近来在用matlab做一些科学计算时,遇到一个问题:       \color{red}{如何把一个数组中的一大部分类似的元素归类并求平均值 / 方差等计算?}
       问题是这样产生的,我在对如下图所示的一个时间序列做阈值判断时,产生了一个数组,模样基本长这样:

例:一个时间序列图
T0 = [300 301 302 303 450 451 452 650 651 652 654]

       这样的一个数组,可以看到里面好多元素是接近的,不过也存在着比较大的跳跃,像是从303到450、452到650,这些跳跃就是时间序列图中的Spike间隔,对于这些逐渐增加的值,我需要一个代表性的元素,例如300或者450,但是随便取一个实在是太过随便,缺乏基本的科学素养,怎么说也要取个平均值或者中位数才能消除误差,得到较为准确的值,这样一来就需要给这个数组中的元素分一下类,只有分出类才能进行下一步的计算,为了找类,其实就是需要找到这个数组的分段下标index的值,也就是说想要达到

T0= [300 301 302 303 || 450 451 452 ||  650 651 652 654]

分成3类这样的效果。

我这里给出相应的matlab代码:

% 目标:找到数组中的分割下标index_cut
abs_small = 10;
index_cut = [];

for i = 2:length(T0)
    delta = T0(1,i) - T0(1,i-1);
    if delta > abs_small
        index_cut = [index_cut,i];
    end
end

% 加上头和尾:得到分割的下标
index_cut = [1,index_cut,length(T0)+1];

% 每一段依次递增的数值求和
time_internal = zeros(1,length(index_cut)-1);
for k = 2:length(index_cut)
    tk1 = index_cut(1,k-1);tk2 = index_cut(1,k);
    time_internal(1,k-1)= sum(T0(1,tk1:(tk2-1)))/(tk2 - tk1);
end

简单说明一下:

  • 首先上来先给定一个最小的差距值abs_small,意思就是超过这个值就不属于当前类了;
  • 动态数组index_cut用来记录原数组T0分类的下标,之所以是动态的是因为没法确定具体的大小;
  • 依次遍历T0中的数组,考察第ii+1个元素的差值,作为分类的标准;
  • 得到下标以后就可以对每一段进行求平均值的操作,注意既然已经分类完就知道具体有几类了(n个下标分n-1类,因为有两个是头和尾哦),所以数组time_imterval直接进行预分配就好。

       为方便各位小伙伴使用该程序,下面附上函数文件,读者复制保存为同名文件即可使用。


function [index_cut,time_internal] = Classify_Array(T0)
%% 目标:找到数组中的分割下标index_cut
abs_small = 10;
index_cut = [];
for i = 2:length(T0)
    delta = T0(1,i) - T0(1,i-1);
    if delta > abs_small
        index_cut = [index_cut,i];
    end
end
% 加上头和尾
index_cut = [1,index_cut,length(T0)+1];

% 每一段依次递增的数值求平均值
time_internal = zeros(1,length(index_cut)-1);
for k = 2:length(index_cut)
    tk1 = index_cut(1,k-1);tk2 = index_cut(1,k);
    time_internal(1,k-1)= sum(T0(1,tk1:(tk2-1)))/(tk2 - tk1);
end

end

       使用时:将你需要分类的数组传入函数Classify_Array既可以得到分类的下标index_cut和每一段的平均值time_internal

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容