【发布时间】:2016-11-26 21:54:59
【问题描述】:
假设我有一个(稀疏)矩阵M 大小(N*N, N*N)。我想从该矩阵中选择元素,其中grid((n,m) 数组,其中n*m=N)的外积为 True(它是布尔二维数组,na=grid.sum())。这可以按如下方式完成
result = M[np.outer( grid.flatten(),grid.flatten() )].reshape (( N, N ) )
result 是一个(na,na) 稀疏数组(和na < N)。上一行是我想要实现的:从grid的乘积中获取M中为真的元素,并将不真的元素挤出数组。
随着n 和m(因此N)增长,而M 和result 是稀疏矩阵,我无法在内存或速度方面有效地做到这一点。我尝试过的最接近的是:
result = sp.lil_matrix ( (1, N*N), dtype=np.float32 )
# Calculate outer product
A = np.einsum("i,j", grid.flatten(), grid.flatten())
cntr = 0
it = np.nditer ( A, flags=['multi_index'] )
while not it.finished:
if it[0]:
result[0,cntr] = M[it.multi_index[0], it.multi_index[1]]
cntr += 1
# reshape result to be a N*N sparse matrix
最后一次整形可以由this approach 完成,但我还没有到那里,因为 while 循环将永远持续下去。
我也尝试过选择 A 的非零元素,然后循环,但这会占用所有内存:
A=np.einsum("i,j", grid.flatten(), grid.flatten())
nzero = A.nonzero() # This eats lots of memory
cntr = 0
for (i,j) in zip (*nzero):
temp_mat[0,cntr] = M[i,j]
cnt += 1
上例中的“n”和“m”约为 300。
【问题讨论】:
-
我在标题中添加了
sparse,因为索引速度比常规numpy数组要慢。 -
虽然
lil最适合索引分配和查找,但通常最好直接操作coo样式的输入数组,然后构建稀疏矩阵。查看sparse.bmat,了解sparseifself 是如何使用coo格式构造复数矩阵的。 -
即使使用
N=4,您的it迭代也需要永远 - 从字面上看。你错过了next(it)。