您创建了一个 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 是必须的。
还有其他匹配形状的方法。例如,如果 x 是 np.matrix 而不是数组,则其列选择将为 (3,1)
In [814]: X= np.matrix(x)
In [816]: X[:,0] = M[:,0].toarray()
使用列表、x[:,[0]] 或切片进行索引也会生成二维列。
在某种程度上,这与最近多次出现的数组/矩阵兼容性问题相同,但稀疏矩阵的使用增加了一个扭曲。