我有以下Python代码:
H = np.zeros(shape=(N-q+1,q),dtype=complex)
for i in range(0,N-q+1):
H[i,:] = u[i:q+i]
其中 N 和 q 是常量, u 是一个足够长的向量,因此当 u时不会发生越界错误[I:q + i]中。
我尝试使用列表推导来优化代码,
H = np.asarray([u[i:q+i] for i in range(0,N-q+1)])
但是 np.asarray()使它比以前的代码慢。
为了优化列值的分配,有什么想法吗?
答案 0 :(得分:2)
您可以使用stride.as_strided
:
import numpy.lib.stride_tricks as stride
s = u.strides[0]
H2 = stride.as_strided(u, shape=(N-q+1,q), strides=(s, s)).astype(complex)
使用strides=(s, s)
是关键 - 特别是,使第一个步幅s
意味着H2
的每一行都将索引推进u
字节数需要推进一个项目。因此行重复,尽管是一次。
例如,
import numpy as np
import numpy.lib.stride_tricks as stride
N, q = 10**2, 6
u = np.arange((N-q+1)*(N))
def using_loop(u):
H = np.zeros(shape=(N-q+1,q),dtype=complex)
for i in range(0,N-q+1):
H[i,:] = u[i:q+i]
return H
def using_stride(u):
s = u.strides[0]
H2 = stride.as_strided(u, shape=(N-q+1,q), strides=(s, s)).astype(complex)
return H2
H = using_loop(u)
H2 = using_stride(u)
assert np.allclose(H, H2)
由于stride.as_strided
避免了Python for-loop
,using_stride
比using_loop
更快。随着N-q
(迭代次数)的增加,优势越来越大。
N = 10 ** 2 using_stride
快5倍:
In [119]: %timeit using_loop(u)
10000 loops, best of 3: 61.6 µs per loop
In [120]: %timeit using_stride(u)
100000 loops, best of 3: 11.9 µs per loop
N = 10 ** 3 using_stride
快28倍:
In [122]: %timeit using_loop(u)
1000 loops, best of 3: 636 µs per loop
In [123]: %timeit using_stride(u)
10000 loops, best of 3: 22.4 µs per loop