【问题标题】:How to replace columns in sparse Matrix Scipy如何替换稀疏矩阵 Scipy 中的列
【发布时间】:2017-10-21 03:34:39
【问题描述】:

我有一个二维维度相同的矩阵 A 和 B A - 是一个零矩阵,从 B 我想只取第一列并将第一个 A.col[0] 替换为 B.col[0]。

我写

data_sims = np.zeros((data.shape[0],data.shape[1]))
data_sims = sparse.csr_matrix(data_sims).tocoo()

我试过这样,但没用

data_sims.getcol(0).toarray = data.getcol(0).toarray()

我什至尝试使用 hstack,但又出现错误 “ValueError:blocks must be 2-D”但它们是相同的二维大小,我错过了什么?请帮帮我。

data_sims = hstack(data.getcol(0).toarray(),data_sims)

【问题讨论】:

  • 标题听起来像是您试图更改稀疏矩阵中的值。但是您的示例正在尝试将稀疏矩阵中的值写入常规数组。

标签: python matrix scipy sparse-matrix


【解决方案1】:

“A”方法的简单教学示例

来到这里希望得到答案,并想尝试以下内容。 我很高兴发现这种“numpy 直观的方法”奏效了。

import numpy as np
import scipy.sparse as ss

m1 = np.array([[1, 4, 7], [2, 5, 8], [3, 6, 9]])
m2 = np.array([[11, 14, 17], [12, 15, 18], [13, 16, 19]])

print(m1, '\n')
print(m2, '\n')

m1 = ss.csc_matrix(m1)
m2 = ss.csc_matrix(m2)

m1 = ss.hstack([m1[:, 0], m2[:, 1], m1[:, 2]])

print(m1.todense())

输出:

[[1 4 7]
 [2 5 8]
 [3 6 9]]

[[11 14 17]
 [12 15 18]
 [13 16 19]]

[[ 1 14  7]
 [ 2 15  8]
 [ 3 16  9]]

【讨论】:

    【解决方案2】:

    您创建了一个 2d numpy 零数组,而不是矩阵或稀疏矩阵。

    In [782]: x = np.zeros((3,2),int)
    In [783]: x.getcol(0)
    ....
    AttributeError: 'numpy.ndarray' object has no attribute 'getcol'
    

    这样的数组没有getcol方法;这是从稀疏矩阵中定义的东西。

    您可以通过索引访问数组的列。结果是一个一维数组。如果要设置列,则需要提供兼容的值,例如另一个一维数组或正确长度的列表。

    In [784]: x[:,0]
    Out[784]: array([0, 0, 0])
    In [785]: x[:,0] = [1,2,3]
    In [786]: x
    Out[786]: 
    array([[1, 0],
           [2, 0],
           [3, 0]])
    

    稀疏矩阵确实有一个getcol:

    In [801]: M = sparse.csr_matrix([[1,0],[0,2],[2,0]])
    In [802]: M
    Out[802]: 
    <3x2 sparse matrix of type '<class 'numpy.int32'>'
        with 3 stored elements in Compressed Sparse Row format>
    In [803]: M.getcol(0)
    Out[803]: 
    <3x1 sparse matrix of type '<class 'numpy.int32'>'
        with 2 stored elements in Compressed Sparse Row format>
    In [804]: M.getcol(0).toarray()
    Out[804]: 
    array([[1],
           [0],
           [2]], dtype=int32)
    In [805]: x[:,0] = M.getcol(0).toarray()
    ....
    ValueError: could not broadcast input array from shape (3,1) into shape (3)
    

    因为M是一个稀疏矩阵,所以是2d的,而getcol也产生了一个2d的稀疏矩阵。即使转换为密集数组,结果也是 2d (3,1)。在这方面它模仿了np.matrix 子类。

    根据广播规则,(3,) 与 (3,1) 不兼容。 ((1,3) 是兼容的)。

    ravel 或 flatten 更正:

    In [806]: x[:,0] = M.getcol(0).toarray().ravel()
    In [807]: x
    Out[807]: 
    array([[1, 0],
           [0, 0],
           [2, 0]])
    

    csr 实现了索引,所以这也有效:

    In [810]: x[:,0] = M[:,0].toarray().ravel()
    

    对于coo 格式,例如Mo = M.tocoo()getcol 是必须的。

    还有其他匹配形状的方法。例如,如果 xnp.matrix 而不是数组,则其列选择将为 (3,1)

    In [814]: X= np.matrix(x)
    In [816]: X[:,0] = M[:,0].toarray()
    

    使用列表、x[:,[0]] 或切片进行索引也会生成二维列。

    在某种程度上,这与最近多次出现的数组/矩阵兼容性问题相同,但稀疏矩阵的使用增加了一个扭曲。

    【讨论】:

      【解决方案3】:

      您可以将列分配给列:

      from scipy import sparse
      import numpy as np
      
      # Target matrix
      A = np.zeros((2, 2))
      
      # Some sparse matrix
      B = sparse.csr_matrix([[5, 6], [7, 8]]).tocoo()
      
      # Assign the first column from B into A
      A[:, 0] = B.tocsc()[:, 0].todense().ravel()
      

      打印出来:

      [[ 5.  0.]
       [ 7.  0.]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-10
        • 1970-01-01
        • 2020-12-07
        • 2017-10-23
        • 2014-12-21
        • 1970-01-01
        • 2016-09-01
        • 2017-01-19
        相关资源
        最近更新 更多