python 如何获取稀疏矩阵元素?

ulydmbyx  于 2023-03-16  发布在  Python
关注(0)|答案(5)|浏览(326)
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,:]应该从第2行中选择元素,而我却通过print A[1,:]从第1行中获取元素。另外,print A[:,0]应该返回第一列,但我什么也没打印出来。为什么?

4si2a6ki

4si2a6ki1#

A[1,:]本身是一个稀疏矩阵,其形状为(1,60877)。This 是您要打印的内容,它只有一行,因此所有行坐标都是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]没有非零元素。

3z6pesqy

3z6pesqy2#

要使用与问题详细信息不同的技术回答标题问题:
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)]
nfg76nw0

nfg76nw03#

如果是用TfidfTransformer计算TFIDF分数,你可以通过tfidf.idf_得到IDF,那么稀疏数组名,比如'a',a.toarray().
toarray返回ndarray;todense返回一个矩阵。如果需要矩阵,请使用todense;否则,使用toarray

nszi6y05

nszi6y054#

我完全承认所有其他给出的答案。这只是一个不同的方法。
为了演示这个例子,我创建了一个新的稀疏矩阵:

from scipy.sparse.csc import csc_matrix
a = csc_matrix([[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]])
print(a)

输出:

(0, 0)  1
(1, 2)  10
(1, 3)  11
(2, 3)  99

为了方便访问,就像访问列表一样,我将其转换为列表。

temp_list = []
for i in a:
    temp_list.append(list(i.A[0]))

print(temp_list)

输出:

[[1, 0, 0, 0], [0, 0, 10, 11], [0, 0, 0, 99]]

这看起来可能很愚蠢,因为我创建了一个稀疏矩阵并将其转换回来,但是有一些函数,如**TfidfVectorizer**和其他函数,会返回一个稀疏矩阵作为输出,处理它们可能会很棘手,这是从稀疏矩阵中提取数据的一种方法。

c0vxltue

c0vxltue5#

这个领域起步较晚,但对于那些寻找一种方法来索引稀疏csr或csc矩阵元素的人来说,可以将非零行、列和数据数组转换为panda Dataframe ,并从矩阵的数据属性中提取元素,这种简单的技术不需要转换为密集数组。
让我们创建稀疏数组。

import numpy as np
import pandas as pd
from scipy import stats
from scipy.sparse import csr_matrix, random
from numpy.random import default_rng

rng = default_rng()
rvs = stats.poisson(25, loc=10).rvs
A = random(5, 5, density=0.25, random_state=rng, data_rvs=rvs)
A.A

产出

array([[32.,  0., 32.,  0.,  0.],
       [ 0., 29.,  0.,  0.,  0.],
       [ 0.,  0.,  0., 30.,  0.],
       [ 0.,  0., 37., 30.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

下面的函数接受稀疏csr或csc矩阵,以及所需的非零行和列索引。

def get_element(matrix, row, col):
    rows, cols = matrix.nonzero()
    d = {"row": rows, "col": cols, "data": matrix.data}
    df = pd.DataFrame(data=d)
    element = df[(df["row"] == row) & (df["col"] == col)]["data"].values[0]
    return element

索引到A[3,2]:

get_element(A, row=3,col=2)

输出:37.0

相关问题