目录
1.csr和ndarray互相转换
2.coo和csr互相转换
3.coo/csr matrix删除列
4.csr matrix删除行
5.coo\csr获取某一行\列
6.coo/csr获取非零条目
在计算中可能会遇到删除稀疏矩阵中某些行或者列,然后构造新的稀疏矩阵的操作,但是numpy中没有提供相应的功能接口,可以自己动手实现。
ndarray->csr
scipy.sparse.csr_matrix(ndarray)
csr->ndarray
ndarray=csr_matrix.A
coo矩阵使用tocsr()、todense()把它转换成CSR或稠密矩阵。
csr矩阵使用tocoo()、todense()把它转换成COO或稠密矩阵。
#输入: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()
可以仿照写删除行的代码
工作需要删除稀疏矩阵的某几行或者列,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))
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))
如果使用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)