有没有一种有效的方法(使用 numpy(来生成一个对称的随机矩阵,其条目均匀分布在 [0,1(中?
设 U 是均匀分布的随机数的方阵。然后,您可以将 U 的下三角形部分与自身转置(仅包括一次对角线(相加,以获得一个对称矩阵,其中包含来自与 U 相同分布的随机数。
import numpy as np
U = np.random.uniform(low=0, high=1.0, size=(1000, 1000))
S = np.tril(U) + np.tril(U, -1).T
print(np.histogram(S.flatten()))
print(np.histogram(S[0,:]))
print(np.histogram(S[:,0]))
矩阵作为一个整体以及任何行或列将由 np.random.uniform 的文档均匀分布在 [0,1( 中
速度方面我得到
%timeit U = np.random.uniform(low=0, high=1.0, size=(1000, 1000))
10.6 ms ± 46.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit S = np.tril(U) + np.tril(U, -1).T
5.76 ms ± 75.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
正如其他人所指出的,你也可以这样做
S = (U + U.T) / 2
以获得对称性,但这将为您提供非对角线中的三角形分布随机数,因为您正在对两个均匀的随机变量求和。
这是一个使用 scipy.spatial.distance.squareform
的方法:
squareform
对称矩阵的完整形式和"压缩"形式之间来回切换:
>>> full = squareform(np.arange(1,11))
>>> full
array([[ 0, 1, 2, 3, 4],
[ 1, 0, 5, 6, 7],
[ 2, 5, 0, 8, 9],
[ 3, 6, 8, 0, 10],
[ 4, 7, 9, 10, 0]])
>>> squareform(full)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
由于它在设计时考虑了距离矩阵,因此将对角线保持在零,因此我们必须手动填充它。为此,我们使用einsum
它使用我们的方式返回对角线的可写视图,
>>> from scipy.spatial.distance import squareform
>>>
>>> N = 5
>>> a = squareform(np.random.random(N*(N-1)//2))
>>> np.einsum('ii->i', a)[:] = np.random.random(N)
>>> a
array([[0.29946651, 0.3636706 , 0.00708741, 0.87536594, 0.62197293],
[0.3636706 , 0.31774527, 0.05597852, 0.10800514, 0.99871399],
[0.00708741, 0.05597852, 0.83912235, 0.86241008, 0.01806965],
[0.87536594, 0.10800514, 0.86241008, 0.11039534, 0.64213608],
[0.62197293, 0.99871399, 0.01806965, 0.64213608, 0.84755054]])