Matlab:按列交错样本

时间:2016-08-16 20:46:52

标签: matlab

在MatLab中我有两个矩阵(矩阵的大小可能不同)。我想从B中抓取列并在A中的每第n列插入它们。

这是一个小例子:

案例I

本案的假设:

列是2的任意倍数,A和B的行是相同的

A =

1 2 3 4
5 6 7 8

B =

1 2
3 4

我想得到这个

c =

1 2 1 3 4 2
5 6 3 7 8 4

代码也适用于不同的情况,例如:

案例II

本案的假设:

列是3的任意倍数,A和B的行是相同的

A =

123456789
123456789

B =

123456
123456

C =

12312 45634 78956
12312 45634 78956

我知道MatLab具有重塑和置换功能,但我无法获得正确的结果。我知道我可以使用for循环,或通过索引手动连接它们,但是考虑使用这些函数会有更好的性能。任何肝脏都会很棒。

3 个答案:

答案 0 :(得分:3)

您需要首先重塑A,使其与B一样宽,垂直连接B,然后将其重新整形为原始高度。

>> C = reshape([reshape(A, [], size(B,2)); B], size(B,1), [])
C =

   1   2   1   3   4   2
   5   6   3   7   8   4

*自然地假设size(A, 1) == size(B, 1)

为了概括这一点,我们可以通过查找列数的gcd找到每个数组的组数:

function C = groupcols(A, B)
% interleave columns of A and B such that
%   for m = number of columns of A, and n = number of columns of B
%   the output matrix C has alternating groups of
%     m / gcd(m,n) columns of A, followed by
%     n / gcd(m,n) columns of B
%   if gcd(m,n) == 1, then C will be all columns of A followed by
%     all columns of B

m = size(A,2);
n = size(B,2);
g = gcd(m,n);

C = [reshape(A, size(A,1)*m/g, []); reshape(B, size(B,1)*n/g, [])];
C = reshape(C, size(A,1), []);

使用输入:

A =

   1   2   3   4   5   6   7   8   9
   1   2   3   4   5   6   7   8   9

B =

   11   12   13   14   15   16
   11   12   13   14   15   16

输出结果为:

1    2    3   11   12    4    5    6   13   14    7    8    9   15   16
1    2    3   11   12    4    5    6   13   14    7    8    9   15   16

由于9列和6列的最大公约数为3,因此有3组,其中A列为3列,B列为2列。

答案 1 :(得分:1)

我想我解决了这个难题:

  • 我将A和B矩阵转换为向量,因为使用向量索引比使用矩阵索引更容易。
  • 我使用索引模数维度准备了A和B元素的正确索引的向量。

检查以下解决方案:

A = [1 2 3 4
     5 6 7 8];

B =[1 2
    3 4];

aN = size(A, 2);
bN = size(B, 2);

cM = size(A,1);
cN = aN + bN;

a = A(:);
b = B(:);

%Initialize vector C with zeros.
c = zeros(length(a) + length(b), 1);

a_indeces = 1:length(c);
b_indeces = 1:length(c);

%Create array of indeces matches rquiered position of A elements.
a_indeces = a_indeces(mod(a_indeces-1, cN) < aN); %[1:4, 7:10]

%Create array of indeces matches rquiered position of B elements (add aN because B elements follows A elements).
b_indeces = b_indeces(mod(b_indeces-1, cN) < bN) + aN; %[5:6, 11:12]

%Fill c elements as vector.
c(a_indeces) = a;
c(b_indeces) = b;

%Reshape c to matrix.
C = reshape(c, [cM, cN]);

我找到了更优雅的方式,效果更好:

A = [ 1   2  3  4
      5   6  7  8
      9  10 11 12];

B =[11 12
    13 14
    15 16];

aN = size(A, 2);
bN = size(B, 2);
cN = aN + bN;

a_indeces = 1:cN;
b_indeces = 1:cN;

%Create array of column indeces matches A elements.
a_indeces = a_indeces(mod(a_indeces-1, floor(cN/bN)) < floor(aN/bN));

%Create array of column indeces matches B elements.
b_indeces = b_indeces(mod(b_indeces-1, floor(cN/bN)) >= floor(aN/bN));

C = zeros(size(A,1), cN);

C(:, a_indeces) = A;
C(:, b_indeces) = B;

答案 2 :(得分:1)

假设A总是正好是B的n倍,您可以使用以下代码生成c:

ngOnInit()

基本思想是首先将A和B水平连接为AB。然后c等于 A = [ 1 2 3 4 5 6; 7 8 9 10 11 12 ] B = [ 13 14; 15 16 ] NA = size(A, 2); NB = size(B, 2); n = NA / NB; # Make a combined array AB = [A B] # Pick columns from A and B part in AB, respectively colsA = reshape(1:NA, [n, NB]) colsB = reshape(1:NB, [1, NB]) + NA cols = [colsA; colsB] c = AB(:, cols(:)) 列索引数组由交错AB(:, [1:n, NA+1, (1:n)+n, NA+2, (1:n)+2*n, NA+3 ... ])[1:n (1:n)+n, (1:n)+2*n... ]生成;两者都可以使用上面的重塑方便地构建。