使用循环对数据进行分组(MATLAB 中的信号处理)
Grouping data using loops (signal processing in MATLAB)
我在 MATLAB 中处理由连续下降组成的信号数据,如下所示。我正在尝试编写一个代码,将每个浸渍的内容分类到一个单独的组中。这样一段代码的大体结构应该是怎样的?
以下是我的数据。我只对低于某个阈值 d(红线)的信号部分感兴趣:
这是所需的分组:
这是一次不成功的尝试:
k=0; % Group number
for i = 1 : length(signal)
if signal(i) < d
k=k+1;
while signal(i) < d
NewSignal(i, k) = signal(i);
i = i + 1;
end
end
end
上面的代码生成了 310 个组,而不是所需的 12 个组。
任何解释将不胜感激。
很简单,您要查找的函数是 bwlabel
,当与逻辑索引结合使用时,这就很简单了。
首先,我制作了一些与您的数据相似的假数据
x=1:1000;
y=sin(x/20);
for ii=1:9
y=y+-10*exp(-(x-ii*100).^2./10);
end
y=awgn(y,4);
plot(x,y)
然后设置阈值并使用 'bwlabel'
d=-4;% set the threshold
groupid=bwlabel(y<d);
bwlabel
在黑白图像中标记连接组,我们在这里有效地做的是在逻辑向量中制作黑白(逻辑 0 和 1)一维图像 y<d
. bwlabel
returns 区域索引处的区域编号。我们对 0 区域不感兴趣,所以要获取第 n 个区域的 x 值或 y 值,只需使用 x(groupid==n)
,例如我的测试数据
x_4=x(groupid==4)
y_4=y(groupid==4)
x_4 = 398 399 400 401 402
y_4 = -5.5601 -7.8280 -9.1965 -7.9083 -5.8751
在 MATLAB 中,您无法更改 for
循环的循环索引。一个 for 循环:
for i = array
依次循环遍历array
的每一列。在您的代码中, 1 : length(signal)
是一个数组,依次访问其每个元素。在这个循环中有一个递增 i
的 while 循环。但是,当此 while 循环结束且 for 循环的下一次迭代运行时,i
将重置为数组中的下一项。
此代码因此需要两个 while
循环:
i = 1; % Index
k = 0; % Group number
while i <= numel(signal)
if signal(i) < d
k = k + 1;
while signal(i) < d
NewSignal(i,k) = signal(i);
i = i + 1;
end
end
i = i + 1;
end
获取 Benl 生成的数据,您可以执行以下操作:
%generate data
x=1:1000;
y=sin(x/20);
for ii=1:9
y=y+-10*exp(-(x-ii*100).^2./10);
end
y=awgn(y,4);
%set threshold
t=-4;
%threshold data
Y = char(double(y<t) + '0'); %// convert to string of zeros and ones
%search for start and ends
这个想法被采纳
[s, e] = regexp(Y, '1+', 'start', 'end');
%and now plot and see that each pair of starts and end
% represents a group
plot(x,y)
hold on
for k=1:numel(s)
line(s(k)*ones(2,1),ylim,'Color','k','LineStyle','--')
line(e(k)*ones(2,1),ylim,'Color','k','LineStyle','-')
end
hold off
legend('Data','Starts','Ends')
评论:首先我选择了一个任意阈值,你可以在你的数据中找到"best"一个。此外,我没有明确地对数据进行分组,而是这种方法为您提供了每个时期的开始和结束时的下降(您可以称之为分组)。所以你可以说每个索引都是分组索引。最后,我没有针对极端情况调试这种方法,当下降落在开始和结束时...
我在 MATLAB 中处理由连续下降组成的信号数据,如下所示。我正在尝试编写一个代码,将每个浸渍的内容分类到一个单独的组中。这样一段代码的大体结构应该是怎样的?
以下是我的数据。我只对低于某个阈值 d(红线)的信号部分感兴趣:
这是所需的分组:
这是一次不成功的尝试:
k=0; % Group number
for i = 1 : length(signal)
if signal(i) < d
k=k+1;
while signal(i) < d
NewSignal(i, k) = signal(i);
i = i + 1;
end
end
end
上面的代码生成了 310 个组,而不是所需的 12 个组。
任何解释将不胜感激。
很简单,您要查找的函数是 bwlabel
,当与逻辑索引结合使用时,这就很简单了。
首先,我制作了一些与您的数据相似的假数据
x=1:1000;
y=sin(x/20);
for ii=1:9
y=y+-10*exp(-(x-ii*100).^2./10);
end
y=awgn(y,4);
plot(x,y)
然后设置阈值并使用 'bwlabel'
d=-4;% set the threshold
groupid=bwlabel(y<d);
bwlabel
在黑白图像中标记连接组,我们在这里有效地做的是在逻辑向量中制作黑白(逻辑 0 和 1)一维图像 y<d
. bwlabel
returns 区域索引处的区域编号。我们对 0 区域不感兴趣,所以要获取第 n 个区域的 x 值或 y 值,只需使用 x(groupid==n)
,例如我的测试数据
x_4=x(groupid==4)
y_4=y(groupid==4)
x_4 = 398 399 400 401 402
y_4 = -5.5601 -7.8280 -9.1965 -7.9083 -5.8751
在 MATLAB 中,您无法更改 for
循环的循环索引。一个 for 循环:
for i = array
依次循环遍历array
的每一列。在您的代码中, 1 : length(signal)
是一个数组,依次访问其每个元素。在这个循环中有一个递增 i
的 while 循环。但是,当此 while 循环结束且 for 循环的下一次迭代运行时,i
将重置为数组中的下一项。
此代码因此需要两个 while
循环:
i = 1; % Index
k = 0; % Group number
while i <= numel(signal)
if signal(i) < d
k = k + 1;
while signal(i) < d
NewSignal(i,k) = signal(i);
i = i + 1;
end
end
i = i + 1;
end
获取 Benl 生成的数据,您可以执行以下操作:
%generate data
x=1:1000;
y=sin(x/20);
for ii=1:9
y=y+-10*exp(-(x-ii*100).^2./10);
end
y=awgn(y,4);
%set threshold
t=-4;
%threshold data
Y = char(double(y<t) + '0'); %// convert to string of zeros and ones
%search for start and ends
这个想法被采纳
[s, e] = regexp(Y, '1+', 'start', 'end');
%and now plot and see that each pair of starts and end
% represents a group
plot(x,y)
hold on
for k=1:numel(s)
line(s(k)*ones(2,1),ylim,'Color','k','LineStyle','--')
line(e(k)*ones(2,1),ylim,'Color','k','LineStyle','-')
end
hold off
legend('Data','Starts','Ends')
评论:首先我选择了一个任意阈值,你可以在你的数据中找到"best"一个。此外,我没有明确地对数据进行分组,而是这种方法为您提供了每个时期的开始和结束时的下降(您可以称之为分组)。所以你可以说每个索引都是分组索引。最后,我没有针对极端情况调试这种方法,当下降落在开始和结束时...