【问题标题】:How to set matrix columns iteratively and fast? [duplicate]如何迭代快速地设置矩阵列? [复制]
【发布时间】:2016-07-27 13:14:04
【问题描述】:

我有以下 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]

其中 Nq 是常量,而 u 是一个足够长的向量,因此当 u 时不会发生越界错误[i:q+i].

我尝试使用列表推导来优化代码,

H = np.asarray([u[i:q+i] for i in range(0,N-q+1)])

但是 np.asarray() 使它比以前的代码慢。

有什么想法可以优化列值的分配吗?

【问题讨论】:

  • 我记得有一个现有的例程可以执行此操作或与之密切相关的操作,但我不记得它是什么。 i 值序列的简单性意味着如果没有现有例程,您可以通过显式步幅操作来完成此操作。
  • 等等,不,我在想别的事。
  • 你能添加一个实际运行的例子吗?

标签: python numpy optimization


【解决方案1】:

你可以使用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

【讨论】:

  • 这个性能怎么样?
  • 很酷。你觉得还有改进的余地吗?
  • 我的 python 讲述了你的跨步示例:最慢的运行时间比最快的运行时间长 6.84 倍。这可能意味着正在缓存中间结果。 100000 次循环,3 次中的最佳:每个循环 9.66 µs。这使得结果可疑
  • 我的意思是,从步幅例程中出来的样本分布很大。我确实重现了巨大的性能提升,所以你的方法很棒。
  • @Chiel:警告可能是由于阵列位于 CPU 缓存中。见stackoverflow.com/q/29759883/190597。由于我对using_loopusing_stride 收到相同的警告,并且它们使用相同的数组,所以我认为比较是公平的。
猜你喜欢
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
  • 2021-12-22
  • 1970-01-01
相关资源
最近更新 更多