python - 如何在 Python 中对角化稀疏 csr 一维矩阵(向量)?

标签 python numpy scipy sparse-matrix

[精简版]

scipy.sparse 中是否有等同于 numpy.diagflat() 的函数?或者有什么方法可以“展平”稀疏矩阵使其变得密集?

[长版]

我有一个稀疏矩阵(数学上是一个向量)x_f,我需要对其进行对角化(即创建一个方矩阵,其对角线上的 x_f 向量的值)。

x_f
Out[59]: 
<35021x1 sparse matrix of type '<class 'numpy.float64'>'
    with 47 stored elements in Compressed Sparse Row format>

我试过 scipy.sparse 模块中的“诊断”。 (我也尝试过'spdiags',但它只是'diags'的更花哨的版本,我不需要它。)我已经尝试过[csr或csc格式],[原始或转置的每种组合vector] 和 [.todense() 或 .toarray()],但我不断收到错误消息:

ValueError: Different number of diagonals and offsets.

对于 sparse.diags,默认偏移量为 0,而我要做的是将数字放在主对角线上(这是默认设置),所以出现此错误意味着它是没有按照我的意愿工作。

以下是分别使用 .todense() 和 .toarray() 的原始向量和转置向量的示例:

x_f_original.todense()
Out[72]: 
matrix([[  0.00000000e+00],
        [  0.00000000e+00],
        [  0.00000000e+00],
        ..., 
        [  0.00000000e+00],
        [  1.03332178e-17],
        [  0.00000000e+00]])

x_f_transposed.toarray()
Out[83]: 
array([[  0.00000000e+00,   0.00000000e+00,   0.00000000e+00, ...,
          0.00000000e+00,   1.03332178e-17,   0.00000000e+00]])

以下代码可以运行,但需要大约 15 秒才能运行:

x_f_diag = sparse.csc_matrix(np.diagflat(x_f.todense()))

有没有人对如何提高效率或更好的方法有任何想法?

[免责声明]

这是我的第一个问题。我希望我做对了,对于任何不清楚的地方,我深表歉意。

最佳答案

In [106]: x_f = sparse.random(1000,1, .1, 'csr')
In [107]: x_f
Out[107]: 
<1000x1 sparse matrix of type '<class 'numpy.float64'>'
    with 100 stored elements in Compressed Sparse Row format>

如果将它变成一维密集数组,我可以在 sparse.diags 中使用它。

In [108]: M1=sparse.diags(x_f.A.ravel()).tocsr()
In [109]: M1
Out[109]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 100 stored elements in Compressed Sparse Row format>

或者我可以将其设为 (1,1000) 矩阵,并使用列表作为偏移量:

In [110]: M2=sparse.diags(x_f.T.A,[0]).tocsr()
In [111]: M2
Out[111]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 100 stored elements in Compressed Sparse Row format>

diags 采用密集的对角线,而不是稀疏的。这是按原样存储的,所以我使用了进一步的 .tocsr 来删除 0 等。

In [113]: sparse.diags(x_f.T.A,[0])
Out[113]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 1000 stored elements (1 diagonals) in DIAgonal format>

所以无论哪种方式,我都将对角线的形状与偏移量(标量或 1)相匹配。

直接映射到 csr(或 csc)可能更快。

对于这种列形状,indices 属性不会告诉我们任何信息。

In [125]: x_f.indices
Out[125]: 
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...0, 0, 0], dtype=int32)

但将其转换为 csc(这将 indptr 映射到 indices)

In [126]: x_f.tocsc().indices
Out[126]: 
array([  2,  15,  26,  32,  47,  56,  75,  82,  96,  99, 126, 133, 136,
       141, 145, 149, ... 960, 976], dtype=int32)
In [127]: idx=x_f.tocsc().indices

In [128]: M3 = sparse.csr_matrix((x_f.data, (idx, idx)),(1000,1000))
In [129]: M3
Out[129]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 100 stored elements in Compressed Sparse Row format>

关于python - 如何在 Python 中对角化稀疏 csr 一维矩阵(向量)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43837454/

相关文章:

numpy - 如何通过固定索引将 4D numpy 数组转换为 2D

python - 对称矩阵的 LDL^T 分解的 Numpy 数组乘法

python - 在非常大的数据集上在 python 中生成 n 选择 2 种组合

python - python中强度函数的积分

python - 如何模拟使用别名导入的函数?

python - 根据索引减少列表

Python SciPy 统计 percentilofscore

java - z 分数和 Java 中的 p 值(生存函数)

python - 等待文件出现和消失?

python - 防止列表推导式中除以零