如何访问稀疏矩阵元素?

68 投票
5 回答
143671 浏览
提问于 2025-04-17 17:19
type(A)
<class 'scipy.sparse.csc.csc_matrix'>
A.shape
(8529, 60877)
print A[0,:]
  (0, 25)   1.0
  (0, 7422) 1.0
  (0, 26062)    1.0
  (0, 31804)    1.0
  (0, 41602)    1.0
  (0, 43791)    1.0
print A[1,:]
  (0, 7044) 1.0
  (0, 31418)    1.0
  (0, 42341)    1.0
  (0, 47125)    1.0
  (0, 54376)    1.0
print A[:,0]
  #nothing returned

我现在不明白的是,A[1,:]应该是选择第二行的元素,但我通过print A[1,:]却得到了第一行的元素。另外,print A[:,0]应该返回第一列的内容,但我什么也没打印出来。为什么会这样呢?

5 个回答

5

如果你是想用 TfidfTransformer 来计算 TFIDF 分数,可以通过 tfidf.idf_ 来获取 IDF 值。然后,假设你有一个稀疏数组,叫做 'a',可以用 a.toarray(). 来处理。

toarray 会返回一个 ndarray;而 todense 会返回一个矩阵。如果你需要矩阵,就用 todense;如果不需要,那就用 toarray

34

为了用一种不同的方法来回答你标题中的问题:

csc_matrix 提供了一个叫 .nonzero() 的方法。

假设有:

>>> import numpy as np
>>> from scipy.sparse.csc import csc_matrix
>>> 
>>> row = np.array( [0, 1, 3])
>>> col = np.array( [0, 2, 3])
>>> data = np.array([1, 4, 16])
>>> A = csc_matrix((data, (row, col)), shape=(4, 4))

你可以通过以下方式获取指向非零数据的索引:

>>> rows, cols = A.nonzero()
>>> rows
array([0, 1, 3], dtype=int32)
>>> cols
array([0, 2, 3], dtype=int32)

然后你可以利用这些索引来访问你的数据,而不需要将稀疏矩阵转换成密集矩阵:

>>> [((i, j), A[i,j]) for i, j in zip(*A.nonzero())]
[((0, 0), 1), ((1, 2), 4), ((3, 3), 16)]
76

A[1,:] 本身就是一个稀疏矩阵,形状是 (1, 60877)。这就是你正在打印的内容,它只有一行,所以所有的行坐标都是 0。

举个例子:

In [41]: a = csc_matrix([[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]])

In [42]: a.todense()
Out[42]: 
matrix([[ 1,  0,  0,  0],
        [ 0,  0, 10, 11],
        [ 0,  0,  0, 99]], dtype=int64)

In [43]: print(a[1, :])
  (0, 2)    10
  (0, 3)    11

In [44]: print(a)
  (0, 0)    1
  (1, 2)    10
  (1, 3)    11
  (2, 3)    99

In [45]: print(a[1, :].toarray())
[[ 0  0 10 11]]

你可以选择列,但如果某一列没有非零元素,使用 print 输出时就什么都不会显示:

In [46]: a[:, 3].toarray()
Out[46]: 
array([[ 0],
       [11],
       [99]])

In [47]: print(a[:,3])
  (1, 0)    11
  (2, 0)    99

In [48]: a[:, 1].toarray()
Out[48]: 
array([[0],
       [0],
       [0]])

In [49]: print(a[:, 1])


In [50]:

最后一次 print 调用没有任何输出,因为列 a[:, 1] 没有非零元素。

撰写回答