哪个是更快的np.vSTACK、np.append、np.comatenate,还是用cython编写的手动函数?

2022-04-04 00:00:00 python numpy performance cython memoryview

问题描述

我编写了一些程序,在每次迭代中更新numpy列表,并对其执行一些操作。迭代次数取决于时间。例如,在1秒内,可能会有1000到2500次迭代。这意味着对于运行程序1秒,数字列表中的项不会超过2500个。

我实现了一个基本算法,但我不确定它是否是计算bonus的最快方法:

import numpy as np

cdef int[:, :] pl_list
cdef list pl_length
cdef list bonus
pl_list = np.array([[8, 7]], dtype=np.int32)

def modify(pl_list, pl_length):
    cdef int k_const = 10
    mean = np.mean(pl_list, axis=0)
    mean = np.subtract(mean, pl_length)
    dev = np.std(pl_list, axis=0)
    mean[0] / dev[0] if dev[0] != 0 else 0
    mean[1] / dev[1] if dev[1] != 0 else 0

    bonus = -1 + (2 / (1 + np.exp(-k_const * mean)))
    return list(bonus)


for i in range(2499): # I just simplified the loop. the main loop works like startTime - time.clock() < seconds
    rand = np.random.randint(8, 64)
    pl_length = [rand, rand-1]

    pl_list = np.append(pl_list, [pl_length], axis=0)
    bonus = modify(pl_list, pl_length)

我想用这些想法来加速这个程序:

  1. 使用np.vstacknp.stacknp.concatenate而不是np.append(pl_list, [pl_length])。(哪一个可能更快?)
  2. 使用自制函数计算np.std,np.均值如下(因为在cython中在内存视图中迭代太快了):

    cdef int i,sm = 0
    for i in range(pl_list.shape[0]):
     ; ;sm += pl_list[i]
    mean = sm/pl_list.shape[0]

  3. 我还在考虑为内存视图定义一个静态长度(如2500),这样我就不需要使用np.append,并且我可以在该数字列表上构建一个队列结构。(队列库怎么样?在此类操作中,这比无用列表更快吗?)

如果我的问题太多太复杂,很抱歉。我只是想在速度上获得最好的表现。


解决方案

忽略modify函数,循环的核心是:

pl_list = np.array([[8, 7]], dtype=np.int32)
....

for i in range(2499):
    ....
    pl_list = np.append(pl_list, [pl_length], axis=0)
    ...

作为一般规则,我们不鼓励在循环中使用np.concatenate及其派生函数。更快的方法是追加到一个列表,并在末尾进行一次连接。(稍后详细说明)

pl_list是列表还是数组?从名称上讲,它是一个列表,但在创建时它是一个数组。我还没有研究过modify,看看它需要数组还是列表。

查看np.append等函数的源代码。基本函数是np.concatenate,它接受一个列表,并沿着指定的轴将它们连接到一个新的数组中。换句话说,它可以很好地处理一长串数组。

np.append用2个参数替换该列表输入。因此,它必须逐一应用。这是一个缓慢的过程。每个追加都会创建一个新数组。

np.hstack只需确保列表元素至少为1维,np.vstack使其为2维,stack添加维度,等等。因此,它们基本上都做同样的事情,只是对输入做了一些微小的调整。

另一种模式是分配一个足够大的数组,例如res = np.zeros((n,2)),然后在res[i,:] = new_value处插入值。速度与列表追加方法大致相同。此模型可以移动到cythontyped memoryviews以获得(潜在的)较大速度提升。

相关文章