2017-10-06 91 views
0

假设与字符串列表的列表如下生成稀疏矩阵给出列表与字符串列表

docs = [["hello", "world", "hello"], ["goodbye", "cruel"]] 

一个人如何去创建一个稀疏矩阵,其中每一行代表上述列表中的子列表和每列代表一个像子列表中的“残忍”的标记字符串。

我看着scipy文档here和一些其他的stackoverflow帖子,但是,这一个是不清楚给我。

row_idx = 0                                 
col_idx = 0                                 
rows = []                                  
cols = []                                  
vals = []                                  
for doc in tokens_list:                              
    col_idx = 0                                
    for token in doc:                               
     rows.append(row_idx)                             
     cols.append(col_idx)                             
     col_idx = col_idx + 1                             
     vals.append(1)                               
    row_idx = row_idx + 1                                                                                         
X = csr_matrix((vals, (rows, cols)))   

我想是这样,但上面我有一种感觉,这是不对的,我不能涉及到SciPy的文档中的例子。

+0

预期产量是多少? – Divakar

+0

你需要使用列表来完成吗?这是非常好的,简单,直接与字典! – agaidis

+0

@Divakar实际的输入是[['isn','t','this','movie','great'],['horrible','horrible','movie']]为[[1,0,1,1,1,1],[0,2,0,1,0,0]]。 – Sanchayan

回答

0

我会创建一个字典,而不是使用列表。然后,你可以有一个元组(行,列)作为你的关键字,该值将是包含在该行,col索引。只需在字典中添加不是null,0等元素的元素即可获得稀疏性。

你也可以用元组替换列表。

0

的例子在csr文档直接生成csr属性,indptrindicesdatacoo的输入是row,coldata。区别在于rowindptr;其他属性是相同的。

乍一看您错过了vocabulary字典。很容易将row与列表中的项目索引匹配。但是col必须以某种方式映射到单词列表或词典。

In [498]: docs = [["hello", "world", "hello"], ["goodbye", "cruel", "world"]] 
In [499]: indptr = [0] 
In [500]: indices = [] 
In [501]: data = [] 
In [502]: vocabulary = {} # a dictionary 
In [503]: for d in docs: 
    ...: ...  for term in d: 
    ...: ...   index = vocabulary.setdefault(term, len(vocabulary)) 
    ...: ...   indices.append(index) 
    ...: ...   data.append(1) 
    ...: ...  indptr.append(len(indices)) 
    ...:  
In [504]: indptr 
Out[504]: [0, 3, 6] 
In [505]: indices 
Out[505]: [0, 1, 0, 2, 3, 1] 
In [506]: data 
Out[506]: [1, 1, 1, 1, 1, 1] 
In [507]: vocabulary 
Out[507]: {'cruel': 3, 'goodbye': 2, 'hello': 0, 'world': 1} 
In [508]: M = sparse.csr_matrix((data, indices, indptr), dtype=int) 
In [510]: M 
Out[510]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 6 stored elements in Compressed Sparse Row format> 
In [511]: M.A 
Out[511]: 
array([[2, 1, 0, 0], 
     [0, 1, 1, 1]]) 

coo输入会是什么样子:

In [515]: Mc = M.tocoo() 
In [516]: Mc.row 
Out[516]: array([0, 0, 0, 1, 1, 1], dtype=int32) 
In [517]: Mc.col 
Out[517]: array([0, 1, 0, 2, 3, 1], dtype=int32) 

所以同一个迭代的作品,除了我们在row列表记录行数:

In [519]: row, col, data = [],[],[] 
In [520]: vocabulary = {} 
In [521]: for i,d in enumerate(docs): 
    ...:  for term in d: 
    ...:   index = vocabulary.setdefault(term, len(vocabulary)) 
    ...:   col.append(index) 
    ...:   data.append(1) 
    ...:   row.append(i) 
    ...:   
In [522]: row 
Out[522]: [0, 0, 0, 1, 1, 1] 
In [523]: col 
Out[523]: [0, 1, 0, 2, 3, 1] 
In [524]: M1 = sparse.coo_matrix((data, (row, col))) 
In [525]: M1 
Out[525]: 
<2x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 6 stored elements in COOrdinate format> 
In [526]: M1.A 
Out[526]: 
array([[2, 1, 0, 0], 
     [0, 1, 1, 1]]) 

'你好' 出现了两次在第一个列表中;所有其他词语只出现一次,或者不出现。 vocabulary具有词和列索引之间的映射。

另一种方法是两次通过。第一个收集所有单词并标识唯一的单词 - 即生成vocabulary或同等单词。然后第二个建立矩阵。