如何迭代和快速设置矩阵列?

时间:2016-04-06 21:43:33

标签: python numpy optimization

我有以下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()使它比以前的代码慢。

为了优化列值的分配,有什么想法吗?

1 个答案:

答案 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-loopusing_strideusing_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