我有时间序列,并且我将一些用户定义的函数应用于时间序列中的每个W元素。
现在我只是使用for循环,大小为W的幻灯片窗口在每次迭代时将我的函数应用于窗口中的元素。
我正在使用Matlab,并且使用“for循环”非常低效,所以我很乐意对此操作进行矢量化。
作为解决方案,我看到将长度为N的信号转换为大小为(N-1,W)的矩阵,其中每一行都是不同窗口中的时间序列,并将函数应用于此矩阵。
所以,我的问题是:
示例:
假设我的时间序列是:
T = [1, 5, 6, 8, 10, 14, 22]
W = 3
X = 1
=>我很想得到
[[1, 5, 6],
[5, 6, 8],
[6, 8, 10],
[8, 10, 14],
[10, 14, 22]]
如果
W = 3
X = 2
=>我很想得到
[[1, 5, 6],
[6, 8, 10],
[10, 14, 22]]
答案 0 :(得分:7)
使用bsxfun
创建正确的索引应该肯定会有所帮助:
ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).');
out = T(ind);
创建正确的索引是第一步,由第一行代码描述。这段代码的作用是创建一个2D矩阵,其中每一行都是每个感兴趣的窗口访问的元素。如果您想直观了解代码如何生成索引,请特别注意X = 1;
和W = 3;
的第一种情况。
我们可以看到第一行包括访问元素1,2,3。第二行包括访问元素2,3,4 ......直到最后一行,即5,6,7。我们可以看到我们必须访问窗口中的相邻元素,因此基本索引需要从1,2,3或一般从1到W
。我们现在需要偏移这些索引,以便它们以每个窗口T
中的正确元素为中心。第一个窗口的偏移量仅为0,第二个窗口的下一个偏移量仅为1,直到最后一行为3.我们看到,对于每一行,随着行的增加,我们再向基本索引添加1个。因此,我们为第二行的每个基本索引添加1,然后为第三行中的每个基本索引添加2,依此类推。如果使用偏移索引添加基本索引,则最终会获得正确的索引以访问T
中的正确元素。
同样,如果X = 2;
和W = 3;
,我们仍然看到基本索引为1,2,3。但是,现在要访问的正确元素是第一行的1,2,3然后是第二行的3,4,5,然后是第三行的5,6,7。对于每一行,我们现在将基本索引偏移 2 而不是现在为1。因此,第二行我们为每个基本索引添加2,然后我们为第三行的每个基本索引添加4,依此类推。
通常,使用向量1:W
创建基本索引,并使用向量0:X:numel(T)-W
创建偏移索引。需要减去W
,以便在按照要求对信号进行采样时不会超出范围。为了创建我们刚才谈到的这些索引,bsxfun
为我们处理了这个问题。
我们创建一个1:W
的行向量,它对应于基本索引和(0:X:numel(T)-W).'
的列向量,它对应于每个窗口的偏移量。请注意,第一个偏移量从0开始,然后我们增加X
个量,以确保计算正确的中心以将基本索引置于。我们停止,直到我们点击numel(T)-W
元素,这是你所说的条件。通过使用bsxfun
,创建了两个临时2D矩阵,其中行向量被复制的行数与列向量中的行一样多,并且列向量被复制为与行矢量。将这两个矩阵一起添加后,就可以得到结果索引矩阵。
使用W = 3;
和X = 1;
运行代码会产生:
>> T = [1, 5, 6, 8, 10, 14, 22];
>> X = 1;
>> W = 3;
>> ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).')
ind =
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
同样,如果W = 3;
和X = 2;
我们也得到:
>> T = [1, 5, 6, 8, 10, 14, 22];
>> X = 2;
>> W = 3;
>> ind = bsxfun(@plus, 1:W, (0:X:numel(T)-W).')
ind =
1 2 3
3 4 5
5 6 7
您可以自己验证这些索引是否与T
中的正确元素相对应,以便在这种情况下创建所需的矩阵。
我们最终使用它来索引我们的矩阵以获取正确的元素:
out = T(ind);
为X = 1;
和W = 3;
执行此操作会给出:
>> out = T(ind)
out =
1 5 6
5 6 8
6 8 10
8 10 14
10 14 22
同样适用于X = 2;
和W = 3;
:
>> out = T(ind)
out =
1 5 6
6 8 10
10 14 22