将字典转换为稀疏矩阵

2024-04-25 09:50:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字典,其中键是用户id,值是该用户喜欢的电影id列表,其中“unique”用户=573000,而“unique”电影=16000。

{1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923],..........}

现在我想把它转换成一个矩阵,行作为用户id,列作为电影id,值为1,表示用户喜欢的电影,即573000*16000

最终,我必须将这个矩阵与它的转置相乘,才能得到与dim(unique电影,unique电影)共现的矩阵。

另外,X'*X操作的时间复杂度是多少(50000012000)。


Tags: 用户id列表字典电影时间矩阵复杂度
3条回答

我认为可以构造一个空的dok_matrix并填充这些值。然后对其进行转置并将其转换为csr_matrix以实现有效的矩阵乘法。

import numpy as np
import scipy.sparse as sp
d = {1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923]}

mat = sp.dok_matrix((573000,16000), dtype=np.int8)

for user_id, movie_ids in d.items():
    mat[user_id, movie_ids] = 1

mat = mat.transpose().tocsr()
print mat.shape
df = {1: [51, 379, 552, 2333, 2335, 4089, 4484], 2: [51, 379, 552, 1674, 1688, 2333, 3650, 4089, 4296, 4484], 5: [783, 909, 1052, 1138, 1147, 2676], 7: [171, 321, 959], 9: [3193], 10: [959], 11: [131,567,897,923],..........}
df2 = pd.DataFrame.from_dict(df, orient='index')
df2 = df2.stack().reset_index()
df2.level_1=1
df2.pivot(index='level_0',columns=0,values='level_1').fillna(0)

这会将dict转换为一个数据帧,然后堆叠以在单独的列中获取用户id和movieid,然后未使用的列级别1的所有值都设置为1。最后一条语句创建一个透视表,用零填充不存在的组合。

您可以立即创建csr_matrix(类似于以下格式:csr_matrix((data, (row_ind, col_ind)))。这是一个关于如何做到这一点的片段。

import scipy.sparse as sp
d = {0: [0,1], 1: [1,2,3], 
     2: [3,4,5], 3: [4,5,6], 
     4: [5,6,7], 5: [7], 
     6: [7,8,9]}
row_ind = [k for k, v in d.items() for _ in range(len(v))]
col_ind = [i for ids in d.values() for i in ids]
X = sp.csr_matrix(([1]*len(row_ind), (row_ind, col_ind))) # sparse csr matrix

您可以使用matrixX在稍后(即X.T * X)找到共现矩阵(credit github@daniel acuna)。我想有一种更快的方法可以将列表字典转换成row_indcol_ind

相关问题 更多 >