coo/csr matrix删除行\列,获取非零条目

目录

1.csr和ndarray互相转换

2.coo和csr互相转换

3.coo/csr matrix删除列

4.csr matrix删除行

5.coo\csr获取某一行\列

6.coo/csr获取非零条目


在计算中可能会遇到删除稀疏矩阵中某些行或者列,然后构造新的稀疏矩阵的操作,但是numpy中没有提供相应的功能接口,可以自己动手实现。

1.csr和ndarray互相转换

ndarray->csr

scipy.sparse.csr_matrix(ndarray)

csr->ndarray

ndarray=csr_matrix.A

2.coo和csr互相转换

coo矩阵使用tocsr()、todense()把它转换成CSR或稠密矩阵。

csr矩阵使用tocoo()、todense()把它转换成COO或稠密矩阵。

3.coo/csr matrix删除列

#输入:M是类型是numpy的csr矩阵或者coo矩阵,idx_to_drop是需要删除的列的index,类型是array,int
#返回:删除指定列之后的csr类型矩阵
    def dropcols_coo(M, idx_to_drop):
        idx_to_drop = np.unique(idx_to_drop)
        C = M.tocoo()
        keep = ~np.in1d(C.col, idx_to_drop)
        C.data, C.row, C.col = C.data[keep], C.row[keep], C.col[keep]
        C.col -= idx_to_drop.searchsorted(C.col)  # decrement column indices
        C._shape = (C.shape[0], C.shape[1] - len(idx_to_drop))
        return C.tocsr()

 可以仿照写删除行的代码

4.csr matrix删除行

工作需要删除稀疏矩阵的某几行或者列,Google了一下,关于此的信息比较少,官方文档中没有找到相关函数,猜测应该是这个功能不常使用,所以官方没有加入。找到一个实现csr_matrix rows remove,但是他仅仅实现了删除一行。所以,自己动手丰衣足食。
建议不知道csr存储原理的,读一下csr的存储原理。

import scipy.sparse as sp
import numpy as np


def del_rows_from_csr_mtx(csr_mtx, row_indices):
    """ 从csr稀疏矩阵中,删除某几行
    思路:
        1. 在data中删除这些行的元素,在indices中删除这些元素的列标。
        2. 在indptr中删除行,同时要修正其余行所对应元素的在data和indices中的位置。
    :param csr_mtx: 原始csr稀疏矩阵
    :param row_indices: 要删除的行,array of int
    :return : 一个新的删除过行的csr矩阵
    """
    if isinstance(csr_mtx, sp.csc_matrix):
        csr_mtx = sp.csr_matrix(csr_mtx)

    indptr = csr_mtx.indptr
    indices = csr_mtx.indices
    data = csr_mtx.data
    m, n = csr_mtx.shape

    # 确认,要删除的元素的在data和indices中的位置
    target_row_ele_indices = [i for idx in row_indices for i in xrange(indptr[idx], indptr[idx+1])]
    # 删除元素和下标
    new_indices = np.delete(indices, target_row_ele_indices)
    new_data = np.delete(data, target_row_ele_indices)

    # 获得因为删除元素所造成的元素位置漂移的偏置量
    off_vec = np.zeros((m+1,), dtype=np.int)
    for idx in row_indices:
        off_vec[idx+1:] = off_vec[idx+1:] + (indptr[idx+1] - indptr[idx])
    # 修正位置
    new_indptr = indptr - off_vec
    # 删除掉这些行
    new_indptr = np.delete(new_indptr, row_indices)

    return sp.csr_matrix((new_data, new_indices, new_indptr), shape=(m-len(row_indices), n))

5.coo\csr获取某一行\列

from scipy import sparse
import numpy as np
matrix = np.array([[9, 8, 7], [6, 5, 4], [3, 2, 1]])
mat= sparse.coo_matrix(matrix)
print(mat.getcol(1))
print(mat.getrow(1))

6.coo/csr获取非零条目

如果使用coo_matrix,这将非常简单,并且coo / csr / csc之间的转换速度非常快。分别获取所有行和列索引可以按如下方式完成:

sp_matrix = sp_matrix.tocoo()
row_ind = sp_matrix.row
col_ind = sp_matrix.col

但是你也可以同时为这些稀疏矩阵类型获得两组索引,这可能是最简单的:

rows, cols = X.nonzero()

如果需要在特定行中查找值,则csc和csr矩阵将返回按行排序的非零条目,而coo似乎返回按列排序的索引。

In [1]: X = coo_matrix(([1, 2, 3, 4, 5, 6], ([0, 2, 2, 0, 1, 2], [0, 0, 1, 2, 2, 2])))
In [2]: X.todense()
Out[2]: 
matrix([[1, 0, 4],
        [0, 0, 5],
        [2, 3, 6]])
In [3]: X.nonzero()
Out[3]: 
(array([0, 2, 2, 0, 1, 2], dtype=int32),
 array([0, 0, 1, 2, 2, 2], dtype=int32))
In [4]: X.tocsr().nonzero()
Out[4]: 
(array([0, 0, 1, 2, 2, 2], dtype=int32),
 array([0, 2, 2, 0, 1, 2], dtype=int32))

参考文献:

1.python - 删除Python中CSR格式矩阵的列 - IT工具网 (coder.work)

2.scipy.sparse中的csr删除行_mantoureganmian的博客-CSDN博客

3.在Python中的稀疏矩阵中按行查找非零条目的快速方法 - 码客 (oomake.com)

你可能感兴趣的:(机器学习)