快速从MATLAB矩阵中删除行和列

17
有没有一种快速的方法在MATLAB中删除大矩阵的行和列?
我有一个非常大的(方)距离矩阵,我想要从中删除若干行/列。
朴素地说:
s = 12000;
D = rand(s);
cols = sort(randsample(s,2))
rows = sort(randsample(s,2)) 

A = D;
tic
A(rows,:) = [];
A(:,cols) = [];
toc
% Elapsed time is 54.982124 seconds.

虽然如此,这个方法非常慢。 奇怪的是,这个方法在这里被建议作为最快的解决方案。

通过预先分配数组并使用布尔索引可以改进此方法。

A = zeros(size(D) - [numel(rows) numel(cols)]);
r = true(size(D,1),1);
c = true(size(D,2),1);
r(rows) = false;
c(cols) = false;

tic
A = D(r,c);
toc
% Elapsed time is 20.083072 seconds.

还有更快的方法吗?

2个回答

9

这似乎是一个内存瓶颈。在我的笔记本电脑上,将D拆分并将这些运算符应用于每个部分要快得多(使用s = 12,000会导致电脑崩溃)。在这里我将其分成两部分,但您可能可以找到更优化的分区。

s = 8000;
D = rand(s);

D1 = D(1:s/2,:);
D2 = D((s/2 + 1):end,:);

cols = sort(randsample(s,2));
rows = sort(randsample(s,2));

A1 = D1;
A2 = D2;

tic
A1(rows(rows <= s/2),:) = [];
A2(rows(rows > s/2) - s/2,:) = [];
A1(:,cols) = [];
A2(:,cols) = [];
toc

A = D;
tic
A(rows,:) = [];
A(:,cols) = [];
toc

Elapsed time is 2.317080 seconds.
Elapsed time is 140.771632 seconds.

1
实际上,当我把分割和合并放在tic/toc里面时,它比朴素方法慢了大约两倍。 - noio
毫不奇怪,我应该在计时中包括那个步骤。当你处理如此庞大的数据集时,性能非常依赖于机器(也许我应该在更好的设备上测试它)。 - MarkV

0

我认为这将取决于您的使用情况,但我有两个想法:

  1. 将其制作成稀疏矩阵。您删除的越多,这个选项可能就越好。
  2. 为什么需要删除这些值?也许您可以尝试:


A = D(randsample(s,2), randsample(s,2));
clear D;
% Use A


问题在于矩阵根据定义不是稀疏的。它是一个距离矩阵,因此每个条目[i,j]是数据集中行ij之间的距离。此外,我读到MATLAB中的稀疏矩阵未针对行或列操作进行优化,因此可能会更慢。而且我实际上需要删除这些条目,并仅使用剩余的条目。 - noio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接