You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于稀疏向量v0与向量列表高效构造(s, n1+n2)维度稀疏矩阵

高效拼接稀疏向量构造大稀疏矩阵的方法

你遇到的这个问题我太懂了——用Scipy稀疏矩阵处理这类批量拼接时,直接套稠密数组的思路确实容易踩坑。先明确下你的核心需求:把单个1×n1的稀疏向量v0,和稀疏向量列表l里的s个1×n2向量逐一拼接,最终得到s行、n1+n2列的稀疏矩阵,还要尽量高效,避免不必要的稠密转换。

为什么你的初始尝试失败?

你最开始写的这段代码:

left = coo_matrix(np.repeat(v0, s))
right = coo_matrix(l)
m = hstack((left, right))

问题出在两处:

  • np.repeat是针对稠密数组设计的,直接作用于稀疏向量v0会先把它转成稠密数组,完全失去稀疏矩阵的内存优势,而且当n1很大时会占用大量内存。
  • coo_matrix(l)不能直接把稀疏向量列表转成按行堆叠的矩阵,得到的结果维度完全不符合预期,自然没法和left做hstack。

而你后来的变通方法:

right = vstack([x for x in l])
left = vstack([v0 for i in range(len(l))])
m = hstack((left, right))

虽然能得到正确结果,但vstack([v0 for ...])本质是重复堆叠s次v0,每次堆叠都要重新整理索引和数据,当s很大时(比如上万级别),效率会非常低。

高效解决方案:直接操作COO矩阵核心数组

Scipy的COO矩阵由row、col、data三个数组定义,我们可以直接操作这三个数组构造目标矩阵,全程保留稀疏特性,完全不用重复堆叠或转稠密数组,效率拉满。

思路分解:

  1. 处理右侧矩阵:把列表l转成s×n2的COO矩阵,同时将右侧矩阵的列索引偏移n1(保证拼接后列索引和左侧衔接)。
  2. 处理左侧矩阵:无需重复堆叠v0,直接扩展v0的row数组为0到s-1的重复,data和col数组重复s次即可。
  3. 合并构造最终矩阵:把左右两侧的row、col、data数组合并,直接生成最终的COO矩阵。

代码示例:

from scipy.sparse import random, coo_matrix, vstack
import numpy as np

s = 10
n1 = 3
n2 = 5

# 生成测试数据
v0 = random(1, n1, format='coo')
l = [random(1, n2, format='coo') for _ in range(s)]

# 处理右侧:转成s×n2的COO矩阵,列索引偏移n1
right_coo = vstack(l, format='coo')
right_coo.col += n1

# 处理左侧:构造s×n1的COO矩阵,直接扩展数组
left_coo = coo_matrix(
    (
        np.tile(v0.data, s),  # 重复s次v0的非零数据
        (
            np.repeat(np.arange(s), v0.nnz),  # 每个行对应v0的所有非零元素
            np.tile(v0.col, s)  # 重复s次v0的列索引
        )
    ),
    shape=(s, n1)
)

# 合并左右数组,生成最终稀疏矩阵
final_coo = coo_matrix(
    (
        np.hstack([left_coo.data, right_coo.data]),
        (
            np.hstack([left_coo.row, right_coo.row]),
            np.hstack([left_coo.col, right_coo.col])
        )
    ),
    shape=(s, n1 + n2)
)

# 可选:转成稠密矩阵验证结果
print(final_coo.todense())

更简洁的替代方案:用克罗内克积构造左侧矩阵

如果你觉得手动处理COO数组麻烦,也可以用kronecker_product快速构造左侧矩阵,代码更简洁且效率同样很高:

from scipy.sparse import kron, eye

# 用克罗内克积生成s×n1的左侧矩阵:s阶单位矩阵 × v0
left_coo = kron(eye(s, format='coo'), v0)

之后再按之前的步骤处理右侧矩阵并合并即可,结果完全一致。

内容的提问来源于stack exchange,提问作者ealain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:39:23