将每个子矩阵n列作为Matlab中新矩阵中的列

时间:2015-07-13 03:57:57

标签: performance matlab matrix

我处理非常大的数据集(数十万列,14行),我需要将每个子矩阵n列作为新矩阵中的列,即

1 3 5 7
2 4 6 8

变为

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

当n = 2时。

我现在所拥有的是

n_data_points = size(data1, 1);
small_n = 60;
big_n = size(data1, 2);

new_2 = bsxfun(@(x,y)(data1(x + n_data_points * (y - 1))), (1:(n_data_points * small_n)).', 1:(big_n - small_n + 1));

但这种方法相当慢。如何使用本机Matlab操作来完成此操作?

修改

因此,在对这里的一些方法进行基准测试并进行更多研究之后,我决定采用以下方法:

n = 60;
[m, big_n] = size(data1);
a = zeros((m*n), (big_n - n + 1));
for i = 1:(big_n - n + 1)
    a(:, i) = reshape(data1(:, i:(i + n - 1)), 1, m*n);
end 

使用14 x 387160矩阵,此方法大约需要2.3秒,而我的原始方法需要大约4.8秒,而@Divakar大约需要3.9。

2 个答案:

答案 0 :(得分:5)

bsxfun使用linear indexing -

的一种方法
[m1,n1] = size(data1)  %// Get size of input array data1
out = data1(bsxfun(@plus,[1:n*m1]',[0:n1-n]*m1))

示例运行 -

data1 =
     9     2     8     2     4     9     4
     9     3     3     3     8     3     6
     5     8     9     6     6     7     1
     2     3     4     5     5     7     1
n =
     3
out =
     9     2     8     2     4
     9     3     3     3     8
     5     8     9     6     6
     2     3     4     5     5
     2     8     2     4     9
     3     3     3     8     3
     8     9     6     6     7
     3     4     5     5     7
     8     2     4     9     4
     3     3     8     3     6
     9     6     6     7     1
     4     5     5     7     1

答案 1 :(得分:1)

对于n = 2,它非常简单:

new_data=[data1(:,1:end-1); data1(:,2:end)];

对于n> 2你可以循环它(我确信它可以在circshiftkron等处完成):

new_data=data1(:,1:end-n+1);
for k=2:n
  new_data=[new_data; data1(:,k:end-n+k)];
end

示例:

n=3;
data1 = randi(10,2,6)

 7     8     5     5     1     1
 8     2     9     2     7     4



new_data =

 7     8     5     5
 8     2     9     2
 8     5     5     1
 2     9     2     7
 5     5     1     1
 9     2     7     4