我需要在SciPy中生成一个高而细的随机列 - 正交矩阵;也就是说,行n
的行数远远大于p
列的数量级(比如n = 1e5
和p = 100
。我知道scipy.stats.ortho_group
1}}生成一个正方形正交矩阵。但是,在我的情况下,生成n
- by - n
随机正交矩阵然后保留第一个p
列是不可行的......是否有更节省时间和空间的方法?
答案 0 :(得分:4)
您可以先生成高而细的随机矩阵,然后执行qr分解。
a = np.random.random(size=(100000, 100))
q, _ = np.linalg.qr(a)
此处q
是您想要的矩阵。
答案 1 :(得分:3)
对我来说AA1 = 1
比scipy.linalg.orth
快一点:
numpy.linalg.qr
答案 2 :(得分:1)
这是一个基准答案。请注意,我进行了一些转置,以便无论该矩阵是高又薄(给定列垂直)或短而宽(给定行垂直),都可以工作。
def qr_method(n, m):
X = np.random.normal(0,1,(n,m))
if n < m:
X = X.T
Q, _ = np.linalg.qr(X)
if n < m:
Q = Q.T
return Q
def orth_method(n, m):
X = np.random.normal(0,1,(n,m))
if n < m:
X = X.T
Q = scipy.linalg.orth(X)
if n < m:
Q = Q.T
return Q
def ortho_group_method(n, m):
Q = scipy.stats.ortho_group.rvs(max(n, m))[:min(n, m),:]
if m < n:
Q = Q.T
return Q
ortho_group
方法(又称方阵然后取一个子集)是如此之慢,以至于我没有将其与其他方法一起作为基准:
%timeit ortho_group_method(500, 20)
2.73 s ± 57.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
在其他两个变量中,差异可以忽略不计,因为QR稍快一些。
%timeit qr_method(10000, 200)
168 ms ± 3.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(10000, 200)
193 ms ± 4.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
基质的高度有区别吗?对于非常高的矩阵,它们接近等效值。
%timeit qr_method(100000, 20)
122 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(100000, 20)
130 ms ± 6.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
对于方矩阵,QR更快。
%timeit qr_method(500, 500)
47.5 ms ± 202 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(500, 500)
137 ms ± 1.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)