Matlab 重塑以垂直平铺上一列下方的列块
在我的脚本中,我生成了一个矩阵,其中每个列至少与另一列耦合。例如,列1与列2耦合,列3与列4耦合,等等。。。但我也可以将3乘3、4乘4或任何其他数字的列耦合起来 目前,这只是一个脑海中的图像,但是我想将耦合列移动到它们自己的行中,这样我就可以使用any()或sum()轻松地将它们混合在一起 通过以下示例,这一点将变得更加清楚:Matlab 重塑以垂直平铺上一列下方的列块,matlab,octave,reshape,tiling,Matlab,Octave,Reshape,Tiling,在我的脚本中,我生成了一个矩阵,其中每个列至少与另一列耦合。例如,列1与列2耦合,列3与列4耦合,等等。。。但我也可以将3乘3、4乘4或任何其他数字的列耦合起来 目前,这只是一个脑海中的图像,但是我想将耦合列移动到它们自己的行中,这样我就可以使用any()或sum()轻松地将它们混合在一起 通过以下示例,这一点将变得更加清楚: A = reshape(1:12, 3, []) % A is the matrix I start with, this reshape is OK A =
A = reshape(1:12, 3, []) % A is the matrix I start with, this reshape is OK
A =
1 4 7 10
2 5 8 11
3 6 9 12
reshape(A, [], 2) % this reshape is not OK
ans =
1 7
2 8
3 9
4 10
5 11
6 12
不过,我希望答案是:
ans =
1 4
2 5
3 6
7 10
8 11
9 12
正如我所说,这个例子只针对2列,但在我的用例中,我还需要支持任意数量的列。这里有3列:
B = reshape(1:18, 3, [])
B =
1 4 7 10 13 16
2 5 8 11 14 17
3 6 9 12 15 18
reshape(B, [], 3)
ans =
1 7 13
2 8 14
3 9 15
4 10 16
5 11 17
6 12 18
我想要的是:
ans =
1 4 7
2 5 8
3 6 9
10 13 16
11 14 17
12 15 18
有没有办法以矢量化的方式做到这一点?假设
M
是输入矩阵,看看这是否适合您-
ncols = 2; %// number of columns (needs to be edited)
[m,n] = size(M) %// get size of input matrix for later usage
r = numel(M)/(m*ncols);
out = reshape(permute(reshape(M,m,ncols,[]),[1 3 2]),m*r,[])
样本运行-
M =
1 4 7 10
2 5 8 11
3 6 9 12
ncols =
2
out =
1 4
2 5
3 6
7 10
8 11
9 12
及
涵盖另一个可能的问题 按照你的说法-
“第1列与第2列耦合,第3列与第4列耦合,等等……但我也可以将第3列与第3列、第4列与第4列或任何其他数字耦合”
,我感觉到您实际上可能希望形成输入矩阵列的所有可能组合,并垂直连接它们以形成一个细长的矩阵作为输出。解决方案的这一部分将涵盖这一基础。实现这样一个目标的代码(如果你希望的话)
是这样的吗-
ncols = 2; %// number of columns (needs to be edited)
[m,n] = size(M) %// get size of input matrix for later usage
combs = dec2base(0:n^2-1,n,ncols)-'0'+1 %// find combinations
combsp = permute(combs,[3 2 1]) %// make a 3D array of those combinations
idx = bsxfun(@plus,[1:m]',(combsp-1)*m) %//'# Indices as a 3D array
idx1 = reshape(permute(idx,[1 3 2]),m*size(idx,3),[]) %// vertically concatenate
%// 3D indices array into a 2D array
out = M(idx1) %// desired output
一次样本运行-
M =
6 7 3 6
3 1 6 3
5 1 4 2
ncols = 2
out =
6 6
3 3
5 5
6 7
3 1
5 1
6 3
3 6
5 4
6 6
3 3 ....
Divakar的解决方案是最好的,但如果你像我一样使用稀疏矩阵和倍频程,倍频程只是不支持N-D稀疏矩阵,所以你不能像Divakar那样重塑: 首先,虽然从根本上讲,有N维空间是可能的 稀疏对象,倍频程稀疏类此时不允许它们 时间稀疏类的所有实例都必须是二维的。这 这意味着SparseMatrix实际上更类似于Octave的矩阵 类比它的标准类 资料来源: 唯一的解决方法是使用基于循环的解决方案,如以下函数:
function B = vertical_tile(A, ncols)
B = [];
if issparse(A)
B = sparse(B);
end
for i=1:ncols
B = [B A(:, i:ncols:end)];
end
B = reshape(B, [], ncols);
end
结果:
vertical_tile(A, 2)
ans =
1 4
2 5
3 6
7 10
8 11
9 12
vertical_tile(B, 3)
ans =
1 4 7
2 5 8
3 6 9
10 13 16
11 14 17
12 15 18
也许答案很好,第一个案例是我想要的,但是第二个案例也会很有用,这解决了另一个我仍然需要解决的问题。然而,这个答案不适用于使用稀疏矩阵的倍频程,因为倍频程还不能处理N-D中的稀疏矩阵,只有2D。。。这就是我的情况。该死的八度音。@user1121352那么,稀疏的东西在第一种或第二种情况下不起作用?当我发布这些方法时,不要以为我脑子里没有什么想法,很抱歉:)我测试了第一个案例,但我想第二个案例也不适用。没关系,我没有在问题中提到稀疏,因为我不知道这个限制,它是特定于八度的。。。我不认为有任何好的方法可以在八度空间中对稀疏矩阵进行垂直平铺,所以你的答案是可以接受的(要么你必须转换为一个密度矩阵,它不能达到稀疏的目的,要么使用一个单元格数组,但它也不能是稀疏的)。此外,根据文档,八度空间的限制是暂时的,希望这将在将来得到解决。
vertical_tile(A, 2)
ans =
1 4
2 5
3 6
7 10
8 11
9 12
vertical_tile(B, 3)
ans =
1 4 7
2 5 8
3 6 9
10 13 16
11 14 17
12 15 18