Python 在一个大矩阵中洗牌较低的三角形

Python 在一个大矩阵中洗牌较低的三角形,python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,我有一个大的稀疏邻接矩阵(64948 x 64948),它在对角线上是对称的。我需要做的是将矩阵的上三角或下三角中非零元素的位置随机化(然后会被转置)。我有下面的代码可以做到这一点。它适用于10x10矩阵,但不适用于64948x64948(我在集群上遇到内存错误)。我意识到我的方法可能有缺陷,如果有人对我如何以更有效的方式做到这一点有任何见解,我将不胜感激 首先,我创建“mask”,它本质上是下三角中每个位置的数组 mask_mtx = np.ones([10,10]) #all ones ma

我有一个大的稀疏邻接矩阵(64948 x 64948),它在对角线上是对称的。我需要做的是将矩阵的上三角或下三角中非零元素的位置随机化(然后会被转置)。我有下面的代码可以做到这一点。它适用于10x10矩阵,但不适用于64948x64948(我在集群上遇到内存错误)。我意识到我的方法可能有缺陷,如果有人对我如何以更有效的方式做到这一点有任何见解,我将不胜感激

首先,我创建“mask”,它本质上是下三角中每个位置的数组

mask_mtx = np.ones([10,10]) #all ones
mask_mtx = np.tril(mask_mtx,-1) #lower triangle ones
mask_mtx = sparse.csr_matrix(mask_mtx)
mask = sparse.find(mask_mtx) #indices of ones
np.save('struc_conn_mat_mask.npy',mask) #cluster fails here when n=64948. I'm trying to save it out from a cluster so I can use the mask on my local machine with code below
len_mask = len(mask[0]) #how many indices there are
mtx = sparse.random(10,10,format='csr',density=0.1) #for the purposes of this example, create random matrix
lmtx = sparse.tril(mtx,-1,format='csr') #lower triangle
tmp_mtx = np.zeros((10,10)) #empty lower triangle to set
lvals = sparse.csr_matrix.count_nonzero(lmtx) #how many 1s in lmtx?
coordinate_indices = random.sample(range(len_mask),lvals) #choose n=lvals random indices to fill with ones
for idx in coordinate_indices:
    tmp_mtx[mask[0][idx]][mask[1][idx]] = 1 #at randomly chosen index from mask, put a 1
tmp_mtx = sparse.csr_matrix(tmp_mtx)
mtx = tmp_mtx + tmp_mtx.T #transpose to upper triangle
出于本例的目的,我将mtx创建为一个数组,但通常我将在65k x 65k csr_矩阵中读取。然后,我在mtx下三角中找到非零元素的数量,并从遮罩中随机选取许多位置。然后,我将1放在一个空的tmp_mtx中的这些位置。最后,我将下三角形转换为上三角形

mask_mtx = np.ones([10,10]) #all ones
mask_mtx = np.tril(mask_mtx,-1) #lower triangle ones
mask_mtx = sparse.csr_matrix(mask_mtx)
mask = sparse.find(mask_mtx) #indices of ones
np.save('struc_conn_mat_mask.npy',mask) #cluster fails here when n=64948. I'm trying to save it out from a cluster so I can use the mask on my local machine with code below
len_mask = len(mask[0]) #how many indices there are
mtx = sparse.random(10,10,format='csr',density=0.1) #for the purposes of this example, create random matrix
lmtx = sparse.tril(mtx,-1,format='csr') #lower triangle
tmp_mtx = np.zeros((10,10)) #empty lower triangle to set
lvals = sparse.csr_matrix.count_nonzero(lmtx) #how many 1s in lmtx?
coordinate_indices = random.sample(range(len_mask),lvals) #choose n=lvals random indices to fill with ones
for idx in coordinate_indices:
    tmp_mtx[mask[0][idx]][mask[1][idx]] = 1 #at randomly chosen index from mask, put a 1
tmp_mtx = sparse.csr_matrix(tmp_mtx)
mtx = tmp_mtx + tmp_mtx.T #transpose to upper triangle
同样,对于10x10矩阵,这种方法也可以,但对于较大的矩阵,这种方法在一些地方会失败。最终,我想做的是一个看似简单的操作——洗牌三角形——但我想不出如何以更有效的方式完成。也许有某种方法可以洗牌列和行(但只针对其中一个三角形?)


任何帮助都会非常非常感谢!谢谢。

这不是我(或其他人)可以在脑海中运行(或可视化)的任务。因此,我能提供帮助的唯一方法是花时间在我的机器上重新创建代码(并查看中间步骤)。但是你说它在较小的尺寸上运行,但在较大的形状上以未指定的方式失败。这不是一个值得测试的东西。洗牌和索引不是scipy.sparse的强项。通常使用矩阵乘法进行索引即使密度为0.1,稀疏矩阵也将有4.2亿个条目,这将占用数千GB的内存。仅数字就需要3.2GB,加上存储稀疏坐标和链接的开销。您可能需要以不同的方式思考您的问题。谢谢您的见解。代表大脑连接体当然是一个数据挑战。如果我发现任何新的东西,我会更新帖子。查看tril_索引而不是tril,在稀疏空间中工作。如果分布均匀,则将其拆分为块