修改csr_matrix的值

更新csr_matrix的值

  • 便捷方式
  • 我的实现...

便捷方式

原文链接
稀疏矩阵如下

import numpy as np
from scipy.sparse import

x = csr_matrix(np.array([[1, 0, 2, 0, 3], 
                         [0, 4, 0, 5, 0]]))

当需要将对其元素小于3的元素修改为0时,很容易想到这种方式

x[x < 3] = 0

但是这种方式在大型稀疏矩阵的情况下会报以下的警告

/home/miniconda3/lib/python3.6/site-packages/scipy/sparse/compressed.py:282: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.
  warn(bad_scalar_msg, SparseEfficiencyWarning)

因为大型稀疏矩阵的情况下,大多数元素都为0,在用<号判断时,很多为0的元素也需要重新赋值,所以这种方式极其不好,可以看到warning中说到>=的判断要更有效率。

那么,我们可以这样来选取,不是所有小于3的元素都置为0,而是在所有非0元素中将小于3的置为0

nonzero_mask = np.array(x[x.nonzero()] < 3)[0]

然后就可以获取相应的行列

rows = x.nonzero()[0][nonzero_mask]
cols = x.nonzero()[1][nonzero_mask]
x[rows, cols] = 0

print(x.todense())
# 最后消除掉0
x.eliminate_zeros()  # This happens inplace
[[0 0 0 0 3]
 [0 4 0 5 0]]

我的实现…

在开发的过程中,经常涉及修改稀疏矩阵的值的操作,之前经常是直接通过csr_matrix的属性遍历修改,需要自己遍历实现修改data里面的内容
修改csr_matrix的值_第1张图片

    import numpy as np
    from scipy.sparse import csr_matrix

    x = csr_matrix(np.array([[1, 0, 2, 0, 3], 
                            [0, 4, 0, 5, 0]]))
    print(x)
    print(x.toarray())
    row, col = x.shape
    # 当data[i][j] < 3时设置为0
    for i in range(row):
        for r in range(x.indptr[i], x.indptr[i+1]):
            if x.data[r] < 3:
                x.data[r] = 0
    print(x.toarray())

输出结果如下, 如果对csr_matrix中的indptr和data属性不清楚,可以参考稀疏矩阵的存储方式

1--- 
   (0, 0)       1
  (0, 2)        2
  (0, 4)        3
  (1, 1)        4
  (1, 3)        5
2--- 
 [[1 0 2 0 3]
 [0 4 0 5 0]]
3--- 
 [[0 0 0 0 3]
 [0 4 0 5 0]]

你可能感兴趣的:(工具)