我有以下函数,它使用一个numpy数组的浮点数和一个整数作为参数。数组中的每一行都计算'是一些实验的结果,我想随机绘制一个实验列表并将它们加起来,然后重复这个过程来创建大量的样本组。
def my_function(counts,nSamples):
''' Create multiple randomly drawn (with replacement)
samples from the raw data '''
nSat,nRegions = counts.shape
sampleData = np.zeros((nSamples,nRegions))
for i in range(nSamples):
rc = np.random.randint(0,nSat,size=nSat)
sampleData[i] = counts[rc].sum(axis=0)
return sampleData
这个函数似乎很慢,通常计数大约有100,000行(和4列),nSamples大约是2000.我尝试使用numba和implicit for循环来尝试加速这段代码但没有成功。 有哪些其他尝试和提高速度的方法?
我已经在函数上运行了cProfile并获得了以下输出。
8005函数调用60.208秒
订购者:标准名称
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 60.208 60.208 <string>:1(<module>)
2000 0.010 0.000 13.306 0.007 _methods.py:31(_sum)
1 40.950 40.950 60.208 60.208 optimize_bootstrap.py:25(bootstrap)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
2000 5.938 0.003 5.938 0.003 {method 'randint' of 'mtrand.RandomState' objects}
2000 13.296 0.007 13.296 0.007 {method 'reduce' of 'numpy.ufunc' objects}
2000 0.015 0.000 13.321 0.007 {method 'sum' of 'numpy.ndarray' objects}
1 0.000 0.000 0.000 0.000 {numpy.core.multiarray.zeros}
1 0.000 0.000 0.000 0.000 {range}
答案 0 :(得分:0)
你确定吗
rc = np.random.randint(0,nSat,size=nSat)
是你想要的,而不是size=someconstant
?否则,您将对包含许多重复的所有行进行求和。
修改强> 是否有助于用矩阵产品替换切片:
rcvec=np.zeros(nSat,np.int)
for i in rc:
rcvec[i]+=1
sampleData[i] = rcvec.dot(counts)
(也许numpy中有一个函数可以让你更快地获得rcvec)
答案 1 :(得分:0)
简单地生成2D
np.random.randint
大小的一次性所有索引,使用它们索引到counts
数组然后沿第一轴求和,就像你在做的那样循环的。
因此,一种矢量化的方式,如此更快的方式,就像这样 -
RC = np.random.randint(0,nSat,size=(nSat, nSamples))
sampleData_out = counts[RC].sum(axis=0)