如何在 m 的窗口中选择序列的 n 个元素? (MATLAB)

发布于 2024-11-30 06:35:39 字数 197 浏览 2 评论 0原文

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

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

Quick MATLAB question.
What would be the best/most efficient way to select a certain number of elements, 'n' in windows of 'm'. In other words, I want to select the first 50 elements of a sequence, then elements 10-60, then elements 20-70 ect.
Right now, my sequence is in vector format(but this can easily be changed).

EDIT:
The sequences that I am dealing with are too long to be stored in my RAM. I need to be able to create the windows, and then call upon the window that I want to analyze/preform another command on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

儭儭莪哋寶赑 2024-12-07 06:35:39

您是否有足够的 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);

Do you have enough RAM to store a 50-by-nWindow array in memory? In that case, you can generate your windows in one go, and then apply your processing on each column

%# 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);
心不设防 2024-12-07 06:35:39

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

n = 50
m = 10;
for i=1:m:length(v)
    w = v(i:i+n);
    % Do something with w
end

To complement Kerrek's answer: if you want to do it in a loop, you can use something like

n = 50
m = 10;
for i=1:m:length(v)
    w = v(i:i+n);
    % Do something with w
end
软的没边 2024-12-07 06:35:39

你的问题描述有点问题。您说您想要“选择序列的前 50 个元素,然后选择元素 10-60...”;然而,这将转化为选择元素:

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

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

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

>> startIndex = 10;
>> sequenceSize = 5;
>> finalSequenceStart = 20;

创建一些示例数据:

>> sampleData = randi(100, 1, 28)

sampleData =

  Columns 1 through 18

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

  Columns 19 through 28

    40    84    81     7    40    53    42    66    63    30

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

>> sequenceStart = startIndex:sequenceSize:finalSequenceStart

sequenceStart =

    10    15    20

创建索引数组以索引到数据数组:

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

index =

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

>> index = index + repmat(sequenceStart, sequenceSize, 1) - 1

index =

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

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

>> sampleData(index)

ans =

    98    83    84
    65     9    81
    81    14     7
    46    18    40
    44    40    53

There's a slight issue with the description of your problem. You say that you want "to select the first 50 elements of a sequence, then elements 10-60..."; however, this would translate to selecting elements:

  • 1-50
  • 10-60
  • 20-70
  • etc.

That first sequence should be 0-10 to fit the pattern which of course in MATLAB would not make sense since arrays use one-indexing. To address this, the algorithm below uses a variable called startIndex to indicate which element to start the sequence sampling from.

You could accomplish this in a vectorized way by constructing an index array. Create a vector consisting of the starting indices of each sequence. For reuse sake, I put the length of the sequence, the step size between sequence starts, and the start of the last sequence as variables. In the example you describe, the length of the sequence should be 50, the step size should be 10 and the start of the last sequence depends on the size of the input data and your needs.

>> startIndex = 10;
>> sequenceSize = 5;
>> finalSequenceStart = 20;

Create some sample data:

>> sampleData = randi(100, 1, 28)

sampleData =

  Columns 1 through 18

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

  Columns 19 through 28

    40    84    81     7    40    53    42    66    63    30

Create a vector of the start indices of the sequences:

>> sequenceStart = startIndex:sequenceSize:finalSequenceStart

sequenceStart =

    10    15    20

Create an array of indices to index into the data array:

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

index =

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

>> index = index + repmat(sequenceStart, sequenceSize, 1) - 1

index =

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

Finally, use this index array to reference the data array:

>> sampleData(index)

ans =

    98    83    84
    65     9    81
    81    14     7
    46    18    40
    44    40    53
淡莣 2024-12-07 06:35:39

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

Use (start : step : end) indexing: v(1:1:50), v(10:1:60), etc. If the step is 1, you can omit it: v(1:50).

影子的影子 2024-12-07 06:35:39

考虑以下矢量化代码:

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 函数(只需编辑 specgram.m 即可查看代码)。

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

Consider the following vectorized code:

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)

The result (truncated for brevity):

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

In fact, the code was adapted from the now deprecated SPECGRAM function from the Signal Processing Toolbox (just do edit specgram.m to see the code).

I omitted parts that zero-pad the sequence in case the sliding windows do not evenly divide the entire sequence (for example x=1:105), but you can easily add them again if you need that functionality...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文