如何将numpy.ndarray转为scipy.sparse.coo_matrix及解决ValueError问题
解决稀疏块对角矩阵转换与ValueError问题
首先,咱们得明确你遇到问题的核心原因:你用了scipy.linalg.block_diag来拼接稀疏矩阵列表,但这个函数是为密集矩阵设计的。当输入是稀疏矩阵时,它不会把这些块合并成一个大的稀疏矩阵,而是会生成一个numpy数组,其中每个元素是单独的稀疏矩阵块——这就是你得到那个(50,50)数组的原因,这完全不是你需要的大的块对角稀疏矩阵。
而你后续尝试用sp.coo_matrix(top5_block.any())或者直接转稀疏矩阵时出错,是因为numpy数组里的元素是稀疏矩阵,对它们做布尔判断(比如any()/all())或者直接传给sp.coo_matrix都会触发歧义判断的错误,这从逻辑上就是错误的操作。
正确解决方案:用scipy.sparse.block_diag
scipy.sparse模块下专门提供了block_diag函数,就是用来拼接稀疏矩阵生成块对角稀疏矩阵的,一步到位,直接返回你需要的scipy稀疏矩阵类型。
修改你的代码如下:
from scipy.sparse import block_diag # 注意是sparse模块下的,不是linalg def build_block_diag(matrice_list): return block_diag(*matrice_list) # 替换成sparse版的block_diag # 假设mat_list是你的50个稀疏矩阵组成的列表 top5_block = build_block_diag(mat_list) print(type(top5_block)) # 输出会是scipy.sparse.coo.coo_matrix或者其他稀疏类型 print(top5_block.shape) # 这里会显示正确的总尺寸,比如所有块的行/列数之和
验证示例
用几个小稀疏矩阵测试,看看效果:
from scipy.sparse import csr_matrix, block_diag # 创建几个小的稀疏矩阵块 block1 = csr_matrix([[1,2],[3,4]]) block2 = csr_matrix([[5]]) block3 = csr_matrix([[6,7,8],[9,10,11]]) # 用sparse.block_diag拼接 big_block = block_diag(block1, block2, block3) print(big_block.toarray()) # 输出: # [[ 1 2 0 0 0] # [ 3 4 0 0 0] # [ 0 0 5 0 0] # [ 0 0 0 6 7 8] # [ 0 0 0 9 10 11]] print(type(big_block)) # <class 'scipy.sparse.coo.coo_matrix'>
转换为torch.sparse张量
得到正确的scipy稀疏矩阵后,你可以直接转换成PyTorch的稀疏张量:
import torch # 先把scipy稀疏矩阵转成coo格式(如果不是的话) coo_matrix = top5_block.tocoo() # 提取行、列、数据 rows = torch.tensor(coo_matrix.row, dtype=torch.long) cols = torch.tensor(coo_matrix.col, dtype=torch.long) values = torch.tensor(coo_matrix.data, dtype=torch.float32) # 创建torch稀疏张量 sparse_tensor = torch.sparse_coo_tensor( indices=torch.stack([rows, cols]), values=values, size=coo_matrix.shape )
这样就完全解决了你的问题:既得到了正确的稀疏块对角矩阵,又能顺利转换成PyTorch需要的稀疏张量,不会再遇到那个ValueError。
内容的提问来源于stack exchange,提问作者mulaixi
相关产品推荐
相关产品推荐

