从Matlab中的数组中提取数字块
Extract blocks of numbers from array in Matlab
我有一个向量,我想从中提取所有块:
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4]
这样我就能得到向量或包含块的单元格:
[1 1 1], [4 4], [5 5], [4], [6], [1], [2], [4 4 4], [9], [8], [4 4 4 4]
有没有不使用 for 循环的有效方法?谢谢!
For 循环并不像您想象的那么慢,尤其是在较新的 Matlab 版本中,尤其是在我们的例子中。也许这会有所帮助
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
breakIdx = [0, find(diff(x)), length(x)];
groups = mat2cell(x,1,diff(breakIdx));
我们通过应用 diff(x)
找到组,并使用 find()
获得组索引。然后只需将组移动到生成的单元格中即可 groups
.
这里很少检查边界情况,所以我建议您添加它。
您可以使用 accumarray
with a custom anonymous function:
y = accumarray(cumsum([true; diff(x(:))~=0]), x(:), [], @(x) {x.'}).';
这给出了一个向量元胞数组。在你的例子中,
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
结果是
y{1} =
1 1 1
y{2} =
4 4
y{3} =
5 5
y{4} =
4
y{5} =
6
y{6} =
1
y{7} =
2
y{8} =
4 4 4
y{9} =
9
y{10} =
8
y{11} =
4 4 4 4
如果在元胞数组中保存所有块不是那么重要,而是关于它们的完整信息,您可以使用此代码:
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
elements = x(diff([0 x])~=0);
block_size = accumarray(cumsum(diff([0 x])~=0).',1).';
blocks = [elements; block_size];
获取双行矩阵,其中元素在第一行,块大小在第二行:
blocks =
1 4 5 4 6 1 2 4 9 8 4
3 2 2 1 1 1 1 3 1 1 4
然后定义一个函数来根据需要创建这些块:
getBlock = @(k) ones(1,blocks(2,k))*blocks(1,k);
并用你想要的块数调用它:
getBlock(8)
获得:
ans =
4 4 4
我有一个向量,我想从中提取所有块:
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4]
这样我就能得到向量或包含块的单元格:
[1 1 1], [4 4], [5 5], [4], [6], [1], [2], [4 4 4], [9], [8], [4 4 4 4]
有没有不使用 for 循环的有效方法?谢谢!
For 循环并不像您想象的那么慢,尤其是在较新的 Matlab 版本中,尤其是在我们的例子中。也许这会有所帮助
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
breakIdx = [0, find(diff(x)), length(x)];
groups = mat2cell(x,1,diff(breakIdx));
我们通过应用 diff(x)
找到组,并使用 find()
获得组索引。然后只需将组移动到生成的单元格中即可 groups
.
这里很少检查边界情况,所以我建议您添加它。
您可以使用 accumarray
with a custom anonymous function:
y = accumarray(cumsum([true; diff(x(:))~=0]), x(:), [], @(x) {x.'}).';
这给出了一个向量元胞数组。在你的例子中,
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
结果是
y{1} =
1 1 1
y{2} =
4 4
y{3} =
5 5
y{4} =
4
y{5} =
6
y{6} =
1
y{7} =
2
y{8} =
4 4 4
y{9} =
9
y{10} =
8
y{11} =
4 4 4 4
如果在元胞数组中保存所有块不是那么重要,而是关于它们的完整信息,您可以使用此代码:
x = [1 1 1 4 4 5 5 4 6 1 2 4 4 4 9 8 4 4 4 4];
elements = x(diff([0 x])~=0);
block_size = accumarray(cumsum(diff([0 x])~=0).',1).';
blocks = [elements; block_size];
获取双行矩阵,其中元素在第一行,块大小在第二行:
blocks =
1 4 5 4 6 1 2 4 9 8 4
3 2 2 1 1 1 1 3 1 1 4
然后定义一个函数来根据需要创建这些块:
getBlock = @(k) ones(1,blocks(2,k))*blocks(1,k);
并用你想要的块数调用它:
getBlock(8)
获得:
ans =
4 4 4