将向量拆分为预定义大小的组
Splitting a vector into groups of a predefined size
我正在寻找一种方法将输入向量分成预定义大小的组,如果有余数,则最后一组较小。我更喜欢将输出作为单元格,但我不介意它是否是任何其他 class,只要它提供使用后续索引访问子组即可。
以下是预期行为的示例:
% 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]);
...这有效,但看起来有点笨拙。有人会提出更优雅的解决方案吗?
一个解决方案使用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:5
和 grpSz = 2
,ceil((1:numel(v))/grpSz)
生成以下数组 [1 1 2 2 3]
。
另一个解决方案,灵感来自(并且很大程度上等同于)obchardon's :
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
which might be faster than splitapply
.
对于大输入,这可能比 accumarray
更快:
out = arrayfun(@(k) v(k:min(k+grpSz-1, end)), 1:grpSz:numel(v), 'UniformOutput', false);
我正在寻找一种方法将输入向量分成预定义大小的组,如果有余数,则最后一组较小。我更喜欢将输出作为单元格,但我不介意它是否是任何其他 class,只要它提供使用后续索引访问子组即可。
以下是预期行为的示例:
% 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]);
...这有效,但看起来有点笨拙。有人会提出更优雅的解决方案吗?
一个解决方案使用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:5
和 grpSz = 2
,ceil((1:numel(v))/grpSz)
生成以下数组 [1 1 2 2 3]
。
另一个解决方案,灵感来自(并且很大程度上等同于)obchardon's
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
which might be faster than splitapply
.
对于大输入,这可能比 accumarray
更快:
out = arrayfun(@(k) v(k:min(k+grpSz-1, end)), 1:grpSz:numel(v), 'UniformOutput', false);