稀疏矩阵的非零元素

3

假设我有一个很大的矩阵X,里面有很多0,为了节省内存和CPU,我将其变成了稀疏矩阵。然后我进行一些操作,最终想要得到非零元素。我的代码大致如下:

 ind = M ~= 0; % Whereby M is the sparse Matrix

对我来说,这看起来有些愚蠢,因为稀疏矩阵的结构应该允许直接提取信息。

澄清一下:我不是在寻找有效的解决方案,而是希望避免重复做同样的事情。稀疏矩阵应该已经知道它的非零值,所以没有必要去查找。

你的 magu_

4个回答

2
直接从稀疏矩阵中检索非零元素的方法是调用 nonzeros()
直接方式显然是最快的方法,但我对稀疏矩阵和其 full() 对应物上的逻辑索引进行了一些测试,前者的索引速度更快(结果取决于矩阵的稀疏模式和维数)。
100 次迭代时间总和如下:
nonzeros:   0.02657 seconds
sparse idx: 0.52946 seconds
full idx:   2.27051 seconds

测试套件:

N = 100;
t = zeros(N,3);
for ii = 1:N
    s = sprand(10000,1000,0.01);
    r = full(s);

    % Direct call nonzeros
    tic
    nonzeros(s);
    t(ii,1) = toc;

    % Indexing sparse
    tic
    full(s(s ~= 0));
    t(ii,2) = toc;

    % Indexing full
    tic
    r(r~=0);
    t(ii,3) = toc;
end

sum(t)

全码和稀疏码的代码或注释似乎被交换了。 - Dennis Jaheruddin
@DennisJaheruddin 他们不是。r已经满了,我需要将s(...)转换为满的才能得到最终结果,而这一步骤正好落在时间上。 - Oleg
是的,这实际上就是我要找的(我的意思是非零元素)。问题是,对我来说两次索引操作看起来很愚蠢。谢谢回答。 - magu_

1

虽然之前已经提出过查找,但我认为这是一个重要的补充:

[r,c,v] = find(M);

该函数不仅返回行列索引 r、c,还返回非零值 v。使用 nonzeros 命令似乎更快,但是在处理稀疏矩阵时,find 命令通常非常有用,因为 [r,c,v] 向量描述了完整的矩阵(除了矩阵维度)。

1
我不确定您的要求,但也许[r c] = find(M)更适合您?通过M(r,c)可以获取M的值,但最好的方法肯定取决于您接下来打算如何处理数据。

1

find函数是MATLAB推荐使用的:

[row,col] = find(X, ...) 返回矩阵X中非零元素的行列索引。 在处理稀疏矩阵时,这种语法尤其有用。


Find函数检索已由稀疏对象存储的子向量。nonzeros()直接检索值,无需任何额外的索引。 - Oleg

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