Python 在速度和内存方面,通过非常大的循环进行迭代并将scipy稀疏矩阵存储到文件中是最有效的方法

Python 在速度和内存方面,通过非常大的循环进行迭代并将scipy稀疏矩阵存储到文件中是最有效的方法,python,numpy,scipy,pickle,bigdata,Python,Numpy,Scipy,Pickle,Bigdata,我有一个23094592(2*10^7)行的表格,其中给出了11701890个独立用户对1000000个独立项目的评级。我正在尝试建立用户与协作过滤项目的评分矩阵(11701890*1000000) 以下是我实现的伪代码: from scipy.sparse import csr_matrix import cPickle totalRows = 23094592 uniqueUsers = 11701890 uniqueItems = 1000000 M = csr_matrix((uniq

我有一个23094592(2*10^7)行的表格,其中给出了11701890个独立用户对1000000个独立项目的评级。我正在尝试建立用户与协作过滤项目的评分矩阵(11701890*1000000)

以下是我实现的伪代码:

from scipy.sparse import csr_matrix
import cPickle

totalRows = 23094592
uniqueUsers = 11701890
uniqueItems = 1000000
M = csr_matrix((uniqueUsers, uniqueItems))
for i in range(totalRows):
      M[userIndex,itemIndex] = ratings[i]
cPickle.dump(M, open('ratings.pkl', 'w+b'))
然而,我一直在google cloud中RAM为52GB的VM上运行这段代码,现在只花了大约2整天的时间来完成大约20%的循环

另外,尽管稀疏矩阵ratings.pkl文件的
M.data.bytes
在某个时间点显示约为
100 MB
,但使用
du-sh
(该文件使用的实际空间要多得多,大约
3 GB

这也导致了内存问题,我不得不在谷歌云中增加虚拟机的磁盘大小

请有人提出任何方法,以更快的方式迭代这个巨大的循环,并更有效地存储稀疏矩阵。

如文档中所述,您可以通过以下方式创建稀疏矩阵:

csr\u矩阵((数据,(行索引,列索引)),[shape=(M,N)])

其中
数据
行索引
列索引
满足关系

a[row\u ind[k],col\u ind[k]]=数据[k]

我尝试了一些随机生成的相同大小的数据,创建矩阵大约需要18秒

from scipy.sparse import csr_matrix
import numpy as np
totalRows = 23094592
UniqueUsers = 11701890
UniqueItems = 1000000
users = np.random.randint(UniqueUsers, size=totalRows)
items = np.random.randint(UniqueItems, size=totalRows)
ratings = np.random.randint(5, size=totalRows)
M = csr_matrix((ratings, (users, items)), shape=(UniqueUsers, UniqueItems))
    
这将创建一个稀疏矩阵,其中
M[users[k],items[k]]=ratings[k]


您应该确保
用户
项目
是每个唯一用户和项目的基于0的索引,也许可以使用scikit learn的LabelEncoder。

您使用的cpu有多少个内核?给定x个内核,您可以创建y个线程,这些线程将在矩阵的不同部分工作,因此让我们来看看假设您有4个内核和8个线程,您可以指定每个线程处理矩阵的1/8,这将优化整个过程。请提供小的(5-7行)可复制的样本(伪)数据集(文本/CSV格式)和所需的数据集。我想可能可以消除循环(使用矢量化操作)-这可能会大大加快整个过程。
pickle
在这里真的不会太好,即使JSON的I/O速度会更快,但仍然不合适。最后可能无法以任何有意义的方式加载最终文件。猜测可能是HDF5格式,但我不能肯定。@roganjosh,描述比较不同的稀疏矩阵保存和加载方法,你没有得到稀疏效率警告吗?迭代创建稀疏矩阵是不好的做法,尤其是使用csr格式。
lil
格式更好。回答非常简洁!