迭代稀疏矩阵并连接每一行的数据和索引

Posted

技术标签:

【中文标题】迭代稀疏矩阵并连接每一行的数据和索引【英文标题】:Iterate over sparse matrix and concatenate data and indicies for each row 【发布时间】:2018-01-31 10:42:43 【问题描述】:

我有一个场景,我有一个数据框和词汇文件,我正试图将其适应数据框字符串列。我正在使用 scikit learn countVectorizer 生成稀疏矩阵。我需要获取稀疏矩阵的输出并将其与数据帧中相应行的数据帧合并。

代码:-

from sklearn.feature_extraction.text import CountVectorizer
docs = ["You can catch more flies with honey than you can with vinegar.",
         "You can lead a horse to water, but you can't make him drink.",
        "search not cleaning up on hard delete",
        "updating firmware version failed",
        "increase not service topology s memory",
        "Nothing Matching Here"
       ]
vocabulary = ["catch more","lead a horse", "increase service", "updating" , "search", "vinegar", "drink", "failed", "not"]

vectorizer = CountVectorizer(analyzer=u'word', vocabulary=vocabulary,lowercase=True,ngram_range=(0,19))

SpraseMatrix = vectorizer.fit_transform(docs)

Below is sparse matrix output - 
  (0, 0)    1
  (0, 5)    1
  (1, 6)    1
  (2, 4)    1
  (2, 8)    1
  (3, 3)    1
  (3, 7)    1
  (4, 8)    1

现在,我要做的是从稀疏矩阵中为每一行构建一个字符串,并将其添加到相应的文档中。

例如:- 对于 doc 3 ("Updating firmware version failed") ,我希望从稀疏矩阵中获取 "3:1 7:1"(即更新和失败的列索引及其频率)并将其添加到 doc数据框的第 3 行。

我在下面尝试过,它会产生扁平输出,因为我希望根据行索引获取子矩阵,循环遍历它并为每一行构建一个连接字符串,例如 "3:1 7:1" ,并且最后,将此字符串作为新列添加到每个相应行的数据框中。

cx = SpraseMatrix .tocoo()
for i,j,v in zip(cx.row, cx.col, cx.data):
        print((i,j,v))

(0, 0, 1)
(0, 5, 1)
(1, 6, 1)
(2, 4, 1)
(2, 8, 1)
(3, 3, 1)
(3, 7, 1)
(4, 8, 1)

【问题讨论】:

【参考方案1】:

我并没有完全按照您的要求进行操作,但lil 格式可能更易于使用:

In [1122]: M = sparse.coo_matrix(([1,1,1,1,1,1,1,1],([0,0,1,2,2,3,3,4],[0,5,6,4,
      ...: 8,3,7,8])))
In [1123]: M
Out[1123]: 
<5x9 sparse matrix of type '<class 'numpy.int32'>'
    with 8 stored elements in COOrdinate format>
In [1124]: print(M)
  (0, 0)    1
  (0, 5)    1
  (1, 6)    1
  (2, 4)    1
  (2, 8)    1
  (3, 3)    1
  (3, 7)    1
  (4, 8)    1
In [1125]: Ml = M.tolil()
In [1126]: Ml.data
Out[1126]: array([list([1, 1]), list([1]), list([1, 1]), list([1, 1]), list([1])], dtype=object)
In [1127]: Ml.rows
Out[1127]: array([list([0, 5]), list([6]), list([4, 8]), list([3, 7]), list([8])], dtype=object)

它的属性是按行组织的,这似乎是你想要的。

In [1130]: Ml.rows[3]
Out[1130]: [3, 7]

In [1135]: for i,(rd) in enumerate(zip(Ml.rows, Ml.data)):
      ...:     print(' '.join(['%s:%s'%ij for ij in zip(*rd)]))
      ...:      
0:1 5:1
6:1
4:1 8:1
3:1 7:1
8:1

您还可以遍历 csr 格式的行,但这需要使用 .indptr 属性进行更多数学运算。

【讨论】:

这正是我想要的。如果可能,也想检查 .indptr 方法。非常感谢!

以上是关于迭代稀疏矩阵并连接每一行的数据和索引的主要内容,如果未能解决你的问题,请参考以下文章

优化 Scipy 稀疏矩阵

稀疏矩阵存储方式

将密集向量与 Tensorflow 中稀疏矩阵的每一行相乘

如何在犰狳中更新稀疏矩阵的值

获取 scipy 稀疏矩阵中每一行的前 n 个项目

稀疏表示字典学习和压缩感知(基本概念)