我编写了一些程序,在每次迭代中更新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(因为在cython中迭代内存视图的速度非常快):
cdef int i,sm = 0
for i in range(pl_list.shape[0]):
sm += pl_list[i]
mean = sm/pl_list.shape[0]
我还在考虑为内存视图定义一个静态长度(如2500),所以我不需要使用np.append
,我可以在那个numpy列表上构建一个队列结构。 (队列库怎么样?在这样的操作中,这比numpy列表更快吗?)
很抱歉,如果我的问题太复杂了。我只是想尽可能提高速度。
答案 0 :(得分:6)
忽略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
只是确保列表元素至少为1d,np.vstack
使它们为2d,stack
添加维度等等。所以基本上它们都做同样的事情,只需稍作调整输入。
另一个模型是分配一个足够大的数组来开始,例如: res = np.zeros((n,2))
,并在res[i,:] = new_value
处插入值。速度与列表追加方法大致相同。此模型可以移至cython
和typed memoryviews
,以便(可能)大幅提升速度。