是否将上三角条目的平面列表复制到完整矩阵?

2024-04-20 10:43:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个平面列表中对称矩阵的上三角条目(包括对角线),我想用它们来填充整个矩阵,包括下面的三角形。最快的方法是什么?在

这是我目前的方法。这么简单的手术似乎要做很多工作。在

import numpy as np
def utri2mat(utri,ntotal):
    iu1 = np.triu_indices(ntotal)
    ret = np.zeros([ntotal,ntotal])
    ret[iu1] = utri
    ret = ret + ret.transpose() - np.diag(ret.diagonal())
    return ret

Tags: 方法importnumpy列表np条目矩阵平面
3条回答

以下是我对一种更快,也可能更好的从平面值生成对称矩阵的方法的提名:

def make_sym(val, n):
    # uses boolean mask
    # uses the same lower tri as np.triu
    mask = ~np.tri(5,k=-1,dtype=bool)
    out = np.zeros((n,n),dtype=val.dtype)
    out[mask] = val
    out.T[mask] = val
    return out

测试:

^{pr2}$

和其他答案一样,它使用out.T[]来分配下三角。在

沃伦的答案使用np.triu_indices,这是where值。这种类型的索引比布尔掩码慢一些。在

但正如我所指出的,Divakar使用的np.triu在早期的numpy版本(例如1.9)中没有返回布尔掩码。这就是促使我深入研究这个问题的原因。在

在1.10中,该函数被改写为:

mask = np.tri(*m.shape[-2:], k=k-1, dtype=bool)
return np.where(mask, np.zeros(1, m.dtype), m)

我通过用where替换~mask来获得一点速度。结果是一样的,只是去掉了一个中间步骤。在

这个版本与您的版本略有不同:

import numpy as np

def utri2mat(utri):
    n = int(-1 + np.sqrt(1 + 8*len(utri))) // 2
    iu1 = np.triu_indices(n)
    ret = np.empty((n, n))
    ret[iu1] = utri
    ret.T[iu1] = utri
    return ret

我换了

^{pr2}$

utri直接赋值给ret的转置:

    ret.T[iu1] = utri

我还删除了参数ntotal,而是根据utri的长度计算出{}必须是什么。在

^{}的启发,您可以使用^{}来设置元素,这样可能非常有效。这里有一个实现它的方法-

def mask_based_utri2mat(utri,ntotal):
    # Setup output array
    out = np.empty((ntotal,ntotal))

    # Create upper triang. mask
    mask = np.triu(np.ones((ntotal,ntotal),dtype=bool))

    # Set upper triang. elements with mask
    out[mask] = utri

    # Set lower triang. elements with transposed mask
    out.T[mask] = utri
    return out    

运行时测试-

^{pr2}$

相关问题 更多 >