如何有效地加载稀疏矩阵?

给定具有此结构的文件:

>单列线是键
>键的非零值

例如:

abc
ef 0.85
kl 0.21
xyz 0.923
cldex 
plax 0.123
lion -0.831

如何创建稀疏矩阵,csr_matrix?

('abc', 'ef') 0.85
('abc', 'kl') 0.21
('abc', 'xyz') 0.923
('cldex', 'plax') 0.123
('cldex', 'lion') -0.31

我试过了:

from collections import defaultdict

x = """abc
ef  0.85
kl  0.21
xyz 0.923
cldex 
plax    0.123
lion    -0.831""".split('\n')

k1 = ''
arr = defaultdict(dict)
for line in x:
    line = line.strip().split('\t')
    if len(line) == 1:
        k1 = line[0]
    else:
        k2, v = line
        v = float(v)
        arr[k1][k2] = v

[OUT]

>>> arr
defaultdict(dict,
            {'abc': {'ef': 0.85, 'kl': 0.21, 'xyz': 0.923},
             'cldex': {'plax': 0.123, 'lion': -0.831}})

具有嵌套的dict结构不如scipy稀疏矩阵结构方便.

有没有办法轻松地将上面给定格式的文件读入任何scipy稀疏矩阵对象?

最佳答案 将@ hpaulj的注释转换为答案,您可以迭代地添加到行和列索引的列表中.稍后,使用pd.factorize,np.unique或sklearn的LabelEncoder对这些进行分解,并转换为稀疏的coo_matrix.

from scipy import sparse
import numpy as np
import pandas as pd

rows, cols, values = [], [], []
for line in x.splitlines():
   if ' ' not in line.strip():
       ridx = line
   else:
       cidx, value = line.strip().split()       
       rows.append(ridx)
       cols.append(cidx)
       values.append(value)

rows, rinv = pd.factorize(rows)
cols, cinv = pd.factorize(cols)

sp = sparse.coo_matrix((values, (rows, cols)), dtype=np.float32)
# sp = sparse.csr_matrix((np.array(values, dtype=np.float), (rows, cols)))
sp.toarray()
array([[ 0.85 ,  0.21 ,  0.923,  0.   ,  0.   ],
       [ 0.   ,  0.   ,  0.   ,  0.123, -0.831]], dtype=float32)

如果需要,您可以使用rinv和cinv执行逆映射(将索引转换为字符串).

点赞