2016-08-14 154 views
2

我有一个大的(79 000 x 480 000)稀疏的csr矩阵。我正尝试删除每个值为< k的所有列(在一定范围内)。Scipy:稀疏矩阵条件去除列

在常规numpy的矩阵这个由面具做法仅仅是:

m = np.array([[0,2,1,1], 
       [0,4,2,0], 
       [0,3,4,0]]) 
mask = (arr < 2) 
idx = mask.all(axis=0) 
result = m[:, ~idx] 
print result 
>>> [[2 1] 
    [4 2] 
    [3 4]] 

的一元位求反运算符〜和布尔面具功能不适用于然而稀疏矩阵。最佳方法是什么:

  1. 获取所有值满足条件的列的索引e < k。
  2. 根据索引列表删除这些列。

需要注意以下几点:

  1. 列代表NGRAM文本功能:有在其中的每个元素都是零矩阵没有列。

正在使用csr矩阵格式,即使这是一个似是而非的选择? 我是否转置并使用.nonzero()?我有相当数量的工作内存(192GB),因此时间效率优于内存效率。

+0

和最终的期望输出将是一个稀疏矩阵或常规NumPy的阵列? – Divakar

+1

这听起来像首先将您的稀疏矩阵转换为CSC(列定位)格式将是一个不错的选择。它等同于CSR格式,不同之处在于它优化了列访问而不是行访问,这会加速您的使用情况。 – perimosocordiae

+0

@Divakar只要不产生OutMemory错误,任何一种情况都是可以接受的。 – GJacobs

回答

3

如果我做

M = sparse.csr_matrix(m) 

M < 2 

我得到一个效率警告;所有M的值为0的像素满足条件,

In [1754]: print(M) 
    (0, 1) 2 
    (0, 2) 1 
    (0, 3) 1 
    (1, 1) 4 
    (1, 2) 2 
    (2, 1) 3 
    (2, 2) 4 
In [1755]: print(M<2) 
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:275: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead. 
    warn(bad_scalar_msg, SparseEfficiencyWarning) 
    (0, 0) True  # not in M 
    (0, 2) True 
    (0, 3) True 
    (1, 0) True # not in M 
    (1, 3) True 
    (2, 0) True # not in M 
    (2, 3) True 
In [1756]: print(M>=2) # all a subset of M 
    (0, 1) True 
    (1, 1) True 
    (1, 2) True 
    (2, 1) True 
    (2, 2) True 

如果I=M>=2;没有all方法,但是有一个sum

In [1778]: np.nonzero(I.sum(axis=0)) 
Out[1778]: (array([0, 0], dtype=int32), array([1, 2], dtype=int32)) 
In [1779]: M[:,np.nonzero(I.sum(axis=0))[1]] 
Out[1779]: 
<3x2 sparse matrix of type '<class 'numpy.int32'>' 
    with 6 stored elements in Compressed Sparse Row format> 
In [1780]: M[:,np.nonzero(I.sum(axis=0))[1]].A 
Out[1780]: 
array([[2, 1], 
     [4, 2], 
     [3, 4]], dtype=int32) 

一般分:

  • In [1760]: I.sum(axis=0) 
    Out[1760]: matrix([[0, 3, 2, 0]], dtype=int32) 
    

    sum使用矩阵乘法

    In [1769]: np.ones((1,3),int)*I 
    Out[1769]: array([[0, 3, 2, 0]], dtype=int32) 
    

    使用nonzero找到非零列实际执行做比较

    时提防那些0值
  • 注意假值上做稀疏矩阵逻辑时

  • 稀疏矩阵的数学优化,尤其是矩阵乘法

  • 稀疏索引ISN”与数组索引相比,功能强大;而且速度也不快。

  • 笔记操作时产生稠密矩阵

+0

谢谢,这个答案让我意识到我无法做我想做的稀疏矩阵操作。我设法通过遍历列来解决它。 – GJacobs