【问题标题】:Get every sub matrix n columns long as column in new matrix in Matlab在Matlab中获取每个子矩阵n列长为新矩阵中的列
【发布时间】:2015-10-01 05:40:15
【问题描述】:

我正在处理非常大的数据集(数十万列,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。

【问题讨论】:

  • 无耻插件:这种操作在R 语言中更容易、更快。如果您要经常处理大数据,您可能需要考虑切换语言。
  • 哦,相信我,我很乐意。我是一名从事研究的本科生,这不取决于我:P

标签: performance matlab matrix


【解决方案1】:

使用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

【讨论】:

  • 为了完整起见,您忘记定义n...虽然它似乎是一个快速的解决方案...
  • @kkuilla 问题将n 作为参数。与data1 相同,它在问题中列为输入数组。是的,bsxfun 似乎是解决这个问题的一个不错的选择,因为它是 built-in: @plus
【解决方案2】:

对于 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

【讨论】:

  • 是的,circshift 或 toeplitz,我猜这里也可以使用其中一个!
  • 这个方法比我的方法慢得多,@Divakar 的 n 值很大。也许您可以提供一个 circshift 或 toeplitz 或 kron 的例子来展示潜力。
猜你喜欢
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
相关资源
最近更新 更多