![](/img/trans.png)
[英]What is the most efficient way to get this kind of matrix from a 1D numpy array?
[英]How to create a symmetric matrix from a numpy 1D array the most efficient way
我有一个1d np.array
。 其长度可能会根据用户输入而有所不同,但始终保持一维。 请告知是否有一种有效的方法可以从中创建对称的2d np.array
? “对称”是指其元素将根据规则k [i,j] = k [j,i]。
我意识到可以使用python for
loop和list
s进行处理,但这效率很低。
提前谢谢了!
示例:例如,我们有x = np.array([1, 2, 3])
。 理想的结果应该是
M = np.array([[1, 2, 3],
[2, 1, 2],
[3, 2, 1])
解释#1
好像您正在重用每一行中的元素。 因此,以这种想法,使用broadcasting
的实现将是-
def symmetricize(arr1D):
ID = np.arange(arr1D.size)
return arr1D[np.abs(ID - ID[:,None])]
样品运行-
In [170]: arr1D
Out[170]: array([59, 21, 70, 10, 42])
In [171]: symmetricize(arr1D)
Out[171]:
array([[59, 21, 70, 10, 42],
[21, 59, 21, 70, 10],
[70, 21, 59, 21, 70],
[10, 70, 21, 59, 21],
[42, 10, 70, 21, 59]])
解释#2
当您想将输入的1D
数组中的元素分配给对称的2D
数组而不重复使用时 ,我有另一种解释,这样我们就可以一次填充上三角部分,然后通过保持对称性来复制下三角区域中的元素在行和列索引之间。 因此,它仅适用于特定的大小。 因此,作为预处理步骤,我们需要执行该错误检查。 经过错误检查之后,我们将初始化输出数组,并使用triangular array
行索引和列索引按原样分配值,并使用交换索引一次在其他三角形部分分配值,从而赋予它对称效应 。
看起来Scipy's squareform
应该可以完成此任务,但是从文档来看,它似乎不支持用输入数组元素填充对角元素。 因此,让我们为解决方案起一个密切相关的名称。
因此,我们将有一个这样的实现-
def squareform_diagfill(arr1D):
n = int(np.sqrt(arr1D.size*2))
if (n*(n+1))//2!=arr1D.size:
print "Size of 1D array not suitable for creating a symmetric 2D array!"
return None
else:
R,C = np.triu_indices(n)
out = np.zeros((n,n),dtype=arr1D.dtype)
out[R,C] = arr1D
out[C,R] = arr1D
return out
样品运行-
In [179]: arr1D = np.random.randint(0,9,(12))
In [180]: squareform_diagfill(arr1D)
Size of 1D array not suitable for creating a symmetric 2D array!
In [181]: arr1D = np.random.randint(0,9,(10))
In [182]: arr1D
Out[182]: array([0, 4, 3, 6, 4, 1, 8, 6, 0, 5])
In [183]: squareform_diagfill(arr1D)
Out[183]:
array([[0, 4, 3, 6],
[4, 4, 1, 8],
[3, 1, 6, 0],
[6, 8, 0, 5]])
您正在寻找的是一种特殊的Toeplitz矩阵,并且易于使用scipy生成
from numpy import concatenate, zeros
from scipy.linalg import toeplitz
toeplitz([1,2,3])
array([[1, 2, 3],
[2, 1, 2],
[3, 2, 1]])
另一个特殊的矩阵解释可以使用Hankel矩阵,它将为您提供给定数组的最小尺寸正方形矩阵。
from scipy.linalg import hankel
a=[1,2,3]
t=int(len(a)/2)+1
s=t-2+len(a)%2
hankel(a[:t],a[s:])
array([[1, 2],
[2, 3]])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.