【发布时间】:2021-09-09 00:38:20
【问题描述】:
我正在尝试使用以下代码从另一个填充稀疏 lil 矩阵的一部分:
adj_mat = sp.dok_matrix((self.n_users + self.m_items, self.n_users + self.m_items), dtype=np.float32)
adj_mat = adj_mat.tolil()
R = self.UserItemNet.tolil()
当我尝试用此代码填充时:
adj_mat[:self.n_users, self.n_users:] = R
adj_mat[self.n_users:, :self.n_users] = R.T
由于超出 RAM 内存 (240Gi),我的进程被杀死。 我的数据集很大:
adj_mat:
<1374194x1374194 sparse matrix of type '<class 'numpy.float32'>'
with 0 stored elements in List of Lists format>
R:
<940696x433498 sparse matrix of type '<class 'numpy.float64'>'
with 24053124 stored elements in List of Lists format>
self.n_users = 940696
有没有更有效的方法来填充这样的列表?
最好的问候
【问题讨论】:
-
我们必须研究它是如何从一个
lil复制到另一个的。太糟糕了,与内存错误消息相反,这是一个杀戮。很高兴知道它走了多远。第一个副本成功了吗?R.T有问题吗?是不是在第二个副本。不幸的是,这不是我想在我的电脑上测试的东西——我不喜欢挂起进程。而且我的内存要小得多。 -
实际上,第一行杀死了该进程。我不知道它走了多远,但我试图在我的一半数据上做到这一点——它也失败了。我只有 1/10 的数据通过了该代码。
-
List of list 是一种极其低效的数据存储方式。永远不要以任何理由使用它。改用首席运营官。
-
挖掘
lil__setitem__代码,它最终使用__set_arrayXarray_sparse,但这会产生“# Fall back to densifying x”。换句话说,它不会尝试找出如何将R的非零值复制到adj_mat,而是执行R.toarray()并进行“常规”分配。所以致密R可能是导致内存错误的原因。 -
@CJR,我怀疑他正在使用
lil,因为它应该最适合索引分配。coo不做索引。我不确定lil格式在内存使用方面是否比coo更糟糕。对于大多数矩阵,csr优于coo是众所周知的。但在这里我认为问题是默认的setitem路由。
标签: python matrix memory scipy sparse-matrix