近来在用matlab做一些科学计算时,遇到一个问题:
问题是这样产生的,我在对如下图所示的一个时间序列做阈值判断时,产生了一个数组,模样基本长这样:

例:一个时间序列图
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中的数组,考察第i和i+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。
