【问题标题】:Splitting a vector into groups of a predefined size将向量拆分为预定义大小的组
【发布时间】:2021-03-26 21:28:28
【问题描述】:

我正在寻找一种将输入向量拆分为预定义大小的组的方法,如果有余数,最后一组会更小。我更喜欢将输出作为单元格,但我不介意它是否是任何其他类,只要它使用后续索引提供对子组的访问即可。

以下是预期行为的示例:

% Even split
v = 1:6;
grpSz = 2;
% OUT: {[1,2], [3,4], [5,6]}

% Remainder
v = 1:5;
grpSz = 3;
% OUT: {[1,2,3], [4,5]}

% Single group
v = 1:5;
grpSz = 6;
% OUT: {[1,2,3,4,5]}

以下是几个有用的数量:

  • 输出中的组数:nG = ceil(numel(v)/grpSz)
  • 最后一组中的元素数:r = mod(numel(v), grpSz)

目前我正在使用mat2cell

function out = evenSplitter(v, grpSz)
nV = numel(v);
nG = ceil(nV/grpSz);
r = mod(nV, grpSz);
out = mat2cell(v, 1, [repmat(grpSz, 1, nG-1), ~r*grpSz+r]);

...可行,但看起来有点笨拙。有人会提出更优雅的解决方案吗?

【问题讨论】:

    标签: matlab vector grouping vectorization matrix-indexing


    【解决方案1】:

    一个使用splitapply的解决方案:

    v     = 1:5;                                           % input array
    grpSz = 2;                                             % maximal group size
    out   = splitapply(@(x){x},v,ceil((1:numel(v))/grpSz)) % split v
    

    此方法适用于所有给定的示例。

    splitapply 将数据分组并应用函数。匿名函数@(x){x} 只是将组中的每个元素放入一个单元格中。并且ceil((1:numel(v))/grpSz) 创建一个数组,指示哪些元素与哪些组相关联。

    例如,如果v = 1:5grpSz = 2ceil((1:numel(v))/grpSz) 生成以下数组[1 1 2 2 3]

    【讨论】:

      【解决方案2】:

      对于大型输入,这可能比 accumarray 更快:

      out = arrayfun(@(k) v(k:min(k+grpSz-1, end)), 1:grpSz:numel(v), 'UniformOutput', false);
      

      【讨论】:

      • 我想用arrayfunUniformOutput 来做这件事,但不能完全拼凑起来……干得好!
      【解决方案3】:

      另一个解决方案,灵感来自(并且很大程度上等同于)obchardon'sanswer

      function out = evenSplitter(v, grpSz)
      idx = ceil((1:numel(v))/grpSz);                       % Group ID of each element
      out = accumarray( idx.', v, [idx(end) 1], @(x){x} );  % idx(end) == nG
      

      这使用accumarray,它可能比splitapply 更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-02
        • 2020-01-14
        • 1970-01-01
        相关资源
        最近更新 更多