如何在Windows中选取一个序列的n个元素?(MATLAB)

4
快速MATLAB问题。在“m”窗口中选择“n”个元素的最佳/最有效方法是什么?换句话说,我想选择序列的前50个元素,然后选择第10-60个元素,然后选择第20-70个元素等。目前,我的序列采用向量格式(但这很容易改变)。
编辑:我正在处理的序列太长,无法存储在我的RAM中。我需要能够创建窗口,然后调用我想要分析/执行其他命令的窗口。

1
为了让窗口长度相同,间隔应该是:1-50,11-60,21-70,... 对吧? - Amro
是的,你说得对,应该是1-50,11-60,21-70等等。我的错误。 - thepro22
5个回答

2
为了补充Kerrek的回答:如果你想在循环中实现它,你可以使用类似于以下的东西:
n = 50
m = 10;
for i=1:m:length(v)
    w = v(i:i+n);
    % Do something with w
end

2

您的计算机内存是否足够存储一个大小为50×n的窗口数组?如果是,您可以一次性生成所有窗口,然后对每列应用处理操作。

%# idxMatrix has 1:50 in first col, 11:60 in second col etc
idxMatrix = bsxfun(@plus,(1:50)',0:10:length(yourVector)-50); %'#

%# reshapedData is a 50-by-numberOfWindows array
reshapedData = yourVector(idxMatrix);

%# now you can do processing on each column, e.g.
maximumOfEachWindow = max(reshapedData,[],1);

抱歉,谢谢你注意到了这个问题 - 我高估了可能的窗口数量 :) - Jonas
这是我最初的想法,但在运行后,我意识到我的序列可能会变得相当长,而我没有足够的RAM来存储数组在内存中。 - thepro22
是否有可能对窗口进行编号,例如“窗口13”,而无需将其存储在RAM中? - thepro22
@thepro22:当然可以:如果windowNumber是13,则窗口#13为stepSize *(windowNumber-1)+(1:windowLength)stepSize是起始索引之间的差异(在您的情况下为10),windowLength是窗口中元素的数量(在您的情况下为50)。 - Jonas

2
您的问题描述有些小问题。您说您想要“选择序列的前50个元素,然后是第10-60个元素...”;但是,这将转化为选择元素:
1-50 10-60 20-70 等等。
第一个序列应该是0-10,以符合模式,当然在MATLAB中这没有意义,因为数组使用单索引。为解决这个问题,下面的算法使用一个名为startIndex的变量来指示从哪个元素开始对序列进行采样。
您可以通过构建索引数组以向量化方式完成此操作。创建一个由每个序列起始索引组成的向量。出于重用的考虑,我将序列长度、序列开始之间的步长和最后一个序列的开始作为变量。在您描述的示例中,序列的长度应为50,步长应为10,最后一个序列的开始取决于输入数据的大小和您的需求。
创建一些示例数据:
创建序列起始索引的向量:
创建用于索引到数据数组中的索引数组:
最后,使用此索引数组引用数据数组:
>> sampleData(index)
回答 =
98 83 84 65 9 81 81 14 7 46 18 40 44 40 53
这段代码是一个示例数据的索引,它返回一个5行3列的矩阵。

1

请考虑以下向量化代码:

x = 1:100;                                     %# an example sequence of numbers

nwind = 50;                                    %# window size
noverlap = 40;                                 %# number of overlapping elements
nx = length(x);                                %# length of sequence

ncol = fix((nx-noverlap)/(nwind-noverlap));    %# number of sliding windows
colindex = 1 + (0:(ncol-1))*(nwind-noverlap);  %# starting index of each

%# indices to put sequence into columns with the proper offset
idx = bsxfun(@plus, (1:nwind)', colindex)-1;   %'

%# apply the indices on the sequence
slidingWindows = x(idx)

结果(为简洁起见截断):
slidingWindows =
     1    11    21    31    41    51
     2    12    22    32    42    52
     3    13    23    33    43    53
    ...
    48    58    68    78    88    98
    49    59    69    79    89    99
    50    60    70    80    90   100

实际上,这段代码是从信号处理工具箱中现已弃用的SPECGRAM函数进行了改编的(只需执行edit specgram.m即可查看代码)。
我省略了一些将序列零填充的部分,以防滑动窗口不能均匀地划分整个序列(例如x=1:105),但如果您需要该功能,可以轻松地再次添加它们...

1
使用 (start : step : end) 索引: v(1:1:50)v(10:1:60) 等等。如果 step1,可以省略它: v(1:50)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接