Python:将矩阵的非对角元素设置为0

Python:将矩阵的非对角元素设置为0,python,numpy,matrix,multidimensional-array,diagonal,Python,Numpy,Matrix,Multidimensional Array,Diagonal,将正方形对称数组的非对角线元素转换为0的最快方法是什么?我会检查保存对角线的速度,然后删除矩阵,然后恢复对角线: n = len(mat) d = mat.ravel()[::n+1] values = d.copy() mat[:,:] = 0 d[:] = values 如果矩阵不是很大,那么仅仅分配一个新的矩阵可能会更快 mat = numpy.diag(numpy.diag(mat)) 以下是一个也适用于非连续阵列的解决方案: a = np.arange(110).reshape(1

将正方形对称数组的非对角线元素转换为0的最快方法是什么?

我会检查保存对角线的速度,然后删除矩阵,然后恢复对角线:

n = len(mat)
d = mat.ravel()[::n+1]
values = d.copy()
mat[:,:] = 0
d[:] = values
如果矩阵不是很大,那么仅仅分配一个新的矩阵可能会更快

mat = numpy.diag(numpy.diag(mat))

以下是一个也适用于非连续阵列的解决方案:

a = np.arange(110).reshape(10, 11)[:, :10]

diag = np.einsum('ii->i', a)
# or if a is not guaranteed to be square
# mn = min(a.shape)
# diag = np.einsum('ii->i', a[:mn, :mn])
save = diag.copy()
a[...] = 0
diag[...] = save

a

# array([[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
#        [  0,  12,   0,   0,   0,   0,   0,   0,   0,   0],
#        [  0,   0,  24,   0,   0,   0,   0,   0,   0,   0],
#        [  0,   0,   0,  36,   0,   0,   0,   0,   0,   0],
#        [  0,   0,   0,   0,  48,   0,   0,   0,   0,   0],
#        [  0,   0,   0,   0,   0,  60,   0,   0,   0,   0],
#        [  0,   0,   0,   0,   0,   0,  72,   0,   0,   0],
#        [  0,   0,   0,   0,   0,   0,   0,  84,   0,   0],
#        [  0,   0,   0,   0,   0,   0,   0,   0,  96,   0],
#        [  0,   0,   0,   0,   0,   0,   0,   0,   0, 108]])

您使用的是哪个版本的numpy?对于1.13.1,行
d[:]=values
导致
ValueError:赋值目的地是只读的
@WarrenWeckesser:你完全正确,出于奇怪的原因
diag
与矩阵共享数据,但却是只读的。然而,使用
ravel
获取具有读写访问权限的矩阵的对角线是很简单的…使用二维数组,
diag
调用;有关只读行为的解释,请参阅其docstring。仅供参考:如果
mat
是C-连续的,则您的解决方案将起作用。例如,它不适用于
mat=np.random.randint(1,10,size=(5,5)).T
,因为
mat.ravel()
将是一个副本。相反,您可以使用
d=as_-striped(mat,stripes=(sum(mat.stripes)),shape=(min(mat.shape),
,其中,
as_-stripped
一起从numpy.lib.stride导入。这很好!我希望TensorFlow张量也有
.einsum()
方法。我们也可以只做
a=a*np.eye(len(a))
。我想应该是一样的,否则会有什么陷阱吗?