python - 哪个更快 np.vstack、np.append、np.concatenate 或在 cython 中制作的手动函数?

标签 python performance numpy cython memoryview

我编写了一些程序来更新 numpy在每次迭代中列出并对其进行一些操作。迭代次数取决于时间。例如在 1 秒内,可能有 1000 到 2500 次迭代。这意味着 numpy 列表中的项目对于运行程序 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)

我正在考虑使用这些想法来加速这个程序:
  • 使用 np.vstack , np.stack或者 np.concatenate而不是 np.append(pl_list, [pl_length]) .(哪个可能更快?)
  • 使用自制函数来计算 np.std, np.mean 像这样(因为在内存 View 中迭代在 cython 中非常快):
    cdef int i,sm = 0for i in range(pl_list.shape[0]): sm += pl_list[i]mean = sm/pl_list.shape[0]
  • 我也在考虑为内存 View 定义一个静态长度(如 2500),所以我不需要使用 np.append我可以在那个 numpy 列表上建立一个队列结构。 (队列库怎么样?在这种操作中它比 numpy 列表快吗?)

  • 对不起,如果我的问题太多和复杂。我只是想在速度上获得最佳性能。

    最佳答案

    忽略 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 个参数替换该列表输入。所以必须反复应用。这是缓慢的。每个 append 都会创建一个新数组。
    np.hstack只需确保列表元素至少为 1d,np.vstack使它们成为 2d,stack添加一个维度等。所以基本上他们都做同样的事情,对输入进行微小的调整。

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

    关于python - 哪个更快 np.vstack、np.append、np.concatenate 或在 cython 中制作的手动函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46102225/

    相关文章:

    performance - 仅过滤包含给定数字集的数字序列

    python - numpy.zeros(n) 和 numpy.zeros(n,1) 之间的区别

    Python - 使用 open/np.load 打开多个文件

    python - 我应该将编码 ='utf-8' 添加到我的 Python 日志记录处理程序吗?

    python - 如何每天运行一次shell脚本?

    performance - 快速模 511 和 127

    python - 如何在加权平均值中避免 NaN?

    python - 解析 XML lxml 我应该跳过或删除注释阻止解析吗

    python - (flask) python mysql - 如何通过 for 循环传递选定的数据并返回它?

    SQL Server BIGINT 或 DECIMAL(18,0) 主键