4

快速的 MATLAB 问题。在“m”的窗口中选择一定数量的元素“n”的最佳/最有效的方法是什么。换句话说,我想选择序列的前 50 个元素,然后是元素 10-60,然后是元素 20-70 等。现在,我的序列是矢量格式(但这很容易改变)。

编辑:我正在处理的序列太长而无法存储在我的 RAM 中。我需要能够创建窗口,然后调用我想要分析/执行另一个命令的窗口。

4

5 回答 5

2

您是否有足够的 RAM 在内存中存储 50×nWindow 数组?在这种情况下,您可以一次性生成窗口,然后在每一列上应用您的处理

%# 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);
于 2011-08-17T21:37:17.533 回答
2

您的问题描述存在小问题。你说你想“选择一个序列的前 50 个元素,然后选择 10-60 个元素……”;但是,这将转化为选择元素:

  • 1-50
  • 10-60
  • 20-70
  • 等等

第一个序列应该是 0-10 以适应模式,这在 MATLAB 中当然没有意义,因为数组使用单索引。为了解决这个问题,下面的算法使用一个名为startIndex的变量来指示从哪个元素开始序列采样。

您可以通过构造索引数组以矢量化方式完成此操作。创建一个由每个序列的起始索引组成的向量。为了重用,我将序列的长度、序列开始之间的步长以及最后一个序列的开始作为变量。在您描述的示例中,序列的长度应为 50,步长应为 10,最后一个序列的开始取决于输入数据的大小和您的需要。

>> 开始索引 = 10;
>> 序列大小 = 5;
>> finalSequenceStart = 20;

创建一些示例数据:

>> 样本数据 = 兰迪 (100, 1, 28)

样本数据 =

  第 1 至 18 列

     8 53 10 82 82 73 15 66 52 98 65 81 46 44 83 9 14 18

  第 19 至 28 列

    40 84 81 7 40 53 42 66 63 30

创建序列起始索引的向量:

>> sequenceStart = startIndex:sequenceSize:finalSequenceStart

序列开始 =

    10 15 20

创建一个索引数组以索引到数据数组中:

>> index = cumsum(ones(sequenceSize, length(sequenceStart)))

指数 =

     1 1 1
     2 2 2
     3 3 3
     4 4 4
     5 5 5

>> 索引 = 索引 + repmat(sequenceStart, sequenceSize, 1) - 1

指数 =

    10 15 20
    11 16 21
    12 17 22
    13 18 23
    14 19 24

最后,使用这个索引数组来引用数据数组:

>> 样本数据(索引)

答案=

    98 83 84
    65 9 81
    81 14 7
    46 18 40
    44 40 53
于 2011-08-17T21:45:01.877 回答
2

为了补充Kerrek的回答:如果你想循环执行,你可以使用类似的东西

n = 50
m = 10;
for i=1:m:length(v)
    w = v(i:i+n);
    % Do something with w
end
于 2011-08-17T21:32:22.370 回答
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

事实上,该代码改编自 Signal Processing Toolbox 中现已弃用的 SPECGRAM 函数(只需edit specgram.m查看代码)。

我省略了对序列进行零填充的部分,以防滑动窗口不能均匀地划分整个序列(例如x=1:105),但如果您需要该功能,您可以轻松地再次添加它们......

于 2011-08-17T22:12:29.637 回答
1

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

于 2011-08-17T21:18:30.423 回答