Matlab:将矩阵重塑为一维数组,重叠元素加在一起

时间:2015-04-23 10:25:48

标签: arrays matlab matrix

以下是一个示例矩阵:

x=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]'; % 1:5 in 1st column, 6:10 in 2nd etc

所以我有:

x=
1 6  11
2 7  12
3 8  13
4 9  14
5 10 15

我想将给定列的元素的上半部分(不包括mid元素)与前一列的下半部分重叠,在重叠中添加元素。第一列和最后一列显然是例外(第一列没有前一列,也没有添加到最后一列)

在上面的简单示例中,为了清楚起见,我重写了这一行以显示重叠的数字:

x=[1,2,3,4,5;
         6,7,8,9,10;
               11,12,13,14,15]';

因此,我希望结果为:

y=[1;2;3;4+6;5+7;8;9+11;10+12;13;14;15];

现在,这只是一个非常简单的例子。生成的代码需要使用大数据进行有效扩展/高效运行。矩阵的可能大小将类似于120000x600,我认为生成的1D阵列将类似于37000000x1

4 个答案:

答案 0 :(得分:5)

回答原始问题(添加移位):

这可以按如下方式完成:

  1. 生成索引向量(ind),使得要求求和的x条目具有相同的索引。这可以使用bsxfun完成。索引可以计算一次并重用于不同的x向量(索引不依赖于x)。
  2. 使用该索引向量与accumarray
  3. 进行求和

    代码:

    n = ceil(size(x,2)/2);
    ind = bsxfun(@plus, 1:size(x,2), (0:size(x,1)-1).'*n); %'// step 1. Valid for any x
    y = accumarray(ind(:), x(:));                          % // step 2. Depends on x
    

    回答已编辑的问题(添加已移位的):

    转置x并按上述步骤继续:

    x = x.';
    n = ceil(size(x,2)/2);
    ind = bsxfun(@plus, 1:size(x,2), (0:size(x,1)-1).'*n);for any x
    y = accumarray(ind(:), x(:));
    

答案 1 :(得分:1)

可以使用一个矩阵矩阵添加计算添加项,然后重新排序结果。

矩阵矩阵加法的形式为

x = [1  2  3  4  5;
     6  7  8  9  10;
     11 12 13 14 15];

A = [4 5; 9 10] + [6 7; 11 12]

第一行和最后一行以及中间列不变。 这将产生以下代码:

x=[1,2,3,4,5;6,7,8,9,10;11,12,13,14,15]';

x = x.';

n = ceil(size(x,2)/2);
m = floor(size(x,2)/2);

A = [x(1:(end-1),(m+1):n) x(2:end,1:m)+x(1:(end-1),(n+1):end)]';

y = [x(1,1:m) A(:)' x(end,(m+1):end)];

结果为y = 1 2 3 10 12 8 20 22 13 14 15

x=rand(120000,600)

需要1.3秒

答案 2 :(得分:0)

这可能是一种方法 -

%// Get size
[n,m] = size(x)

%// Indices of first overlapping elements and its length
first_overlap = ceil(n/2)+1:n
overlap_len = numel(first_overlap)

%// Store the last elements of overlapping length to be appended at final stage
rem_ele = x(end-numel(first_overlap)+1:end)

%// Indices of overlapping elements across all columns
idx = bsxfun(@plus,first_overlap(:),[0:m-2]*n)

%// Do summations of overlaps and store back tto the next group of overlaps
x(idx(:)+overlap_len) = x(idx(:)) + x(idx(:)+overlap_len)

%// Remove elements from the previous overlaps
x(end-overlap_len+1:end,:)=[]

%// Output array after appending rem_ele to column vector version of modified x
out = [x(:) ; rem_ele(:)]

答案 3 :(得分:0)

可能不是最具扩展性的解决方案,但可能是一个可读且直观的解决方案:

% Split the matrix into three parts
left  = x(:,1:floor(end/2));
mid   = x(:,floor(end/2)+1:ceil(end/2));
right = x(:,ceil(end/2)+1:end);

% Extend the middle part by one, note that this works even if mid is empty
mid(end+1,:) = nan;

% Construct a new matrix by summing up left and right parts
X = [left(1,:); ...
     left(2:end,:) + right(1:end-1,:); ...
     right(end,:)];

% Add the midpoints back
X=[X, mid].';

% Reshape into vector and remove the possible extra mid point 
y = X(1:end-~isempty(mid));