我经常在Stack Overflow上潜伏一段时间,每当我遇到编码问题时,我都会从这里找到非常有用和清晰的信息。但是,我现在似乎无法找到解决我今天特定问题的线索。
今天早些时候,我了解了Python中的矢量化函数,以加快计算时间。我目前正在尝试优化一个月前编写的python程序。我的程序采用包含以下格式数据的文本文件:
<magnitude> <dmagnitude> <exposure_number>
然后我将每列分配到列表mag
,dmag
和expnum
。
我想要做的是创建共享相同mag
的{{1}}和dmag
值的二维数组(具有相同的曝光数量意味着expnum
并且mag
指向同一数据点)。
我为所有曝光数字执行此操作,最后,我采用dmag
和mag
的中位数,以及每个曝光的dmag
的标准偏差基于数字的数组并将它们组合成一个我可以绘制的数组。
目前,我有以下代码:
mag
然后我准备好from numpy import loadtxt,array,asarray,append,std,median,empty,take
data = loadtxt(infile,usecols=(0,1,2))
mag = data1[:,2].tolist()
dmag = data1[:,3].tolist()
expnum = data1[:,4].tolist()
#initialize variables
indexing = list()
master_mag = list()
master_dmag = list()
sub_mag = list()
sub_dmag = list()
mag_std = array([])
mag_stdmed = array([])
mag_med = array([])
while len(mag) > 0:
num=expnum[0]
for i in range(0,len(expnum)):
if expnum[i] == num:
sub_mag.append(mag[i])
sub_dmag.append(dmag[i])
indexing.append(i)
#add the sub lists to their master lists
master_mag.append(sub_mag)
master_dmag.append(sub_dmag)
sub_mag=list()
sub_dmag=list()
#remove from mag, dmag, and expnum the index referred to by indexing
while len(indexing) > 0:
mag.pop(indexing[-1])
dmag.pop(indexing[-1])
expnum.pop(indexing[-1])
indexing.pop()
#make the master mag and dmag lists into numpy arrays
master_mag=asarray(master_mag)
master_dmag=asarray(master_dmag)
#generate the mag and dmag median and mag std arrays
for i in range(0,len(master_mag)):
mag_std=append(mag_std,std(master_mag[i]))
mag_med=append(mag_med,median(master_mag[i]))
mag_stdmed=append(mag_stdmed,median(master_dmag[i]))
#create empty numpy arrays to be used for mag med vs. mag std
#and mag med vs. dmag med
med_std=empty([0,2])
med_dmed=empty([0,2])
#fill in those arrays
for i in range(0,len(mag_std)):
med_std=append(med_std,[[mag_med[i],mag_std[i]]],axis=0)
med_dmed=append(med_dmed,[[mag_med[i],mag_stdmed[i]]],axis=0)
#sort the median mag and dmag standard deviation arrays by median mag
order_med_std=med_std[:,0].argsort()
order_med_dmed=med_dmed[:,0].argsort()
sorted_med_std=take(med_std,order_med_std,0)
sorted_med_dmed=take(med_dmed,order_med_dmed,0)
与sorted_med_dmed[:,0]
和sorted_med_dmed[:,1]
与sorted_med_std[:,0]
这段代码有效,只是我觉得它太慢了(特别是当我获得超过10,000个数据点时)。我想尝试对这段代码进行矢量化以使其更快,但我不知道从哪里开始。
我想帮助弄清楚如何对匹配的曝光数字组件进行矢量化。我想在开始时创建一个多维数组,其格式为:sorted_med_std[:,1]
,长度等于不同曝光数的数量。有没有办法在线生成和更新这样的数组,而不必使用大量的循环?
如果您需要进一步明确此代码的用途,请与我们联系。
感谢您的时间。
答案 0 :(得分:2)
像这样的任何问题的第一步应始终是分析。我建议尝试line_profiler,因为这样可以直观地查找热点。 (您也可以尝试Python的内置探查器,但我发现它的输出更难解析。)
这应该可以让您了解哪些部分最能减慢代码速度。如果不自己尝试,我可以提供一些建议:
append
,列表很快,但对于大多数其他操作来说速度很慢,而且它们不支持向量化。numpy.append
。每次调用都涉及分配更多内存和复制,这在循环中可能非常慢。使用词典按键分组数据。我发现stdlib collections.defaultdict
对于这样的分组非常有用:
groups = defaultdict(list)
for a,b,key in data:
groups[key].append((a,b))
使用numpy的自动向量化函数调用,而不是在循环中调用函数。例如,此代码:
#generate the mag and dmag median and mag std arrays
for i in range(0,len(master_mag)):
mag_std=append(mag_std,std(master_mag[i]))
mag_med=append(mag_med,median(master_mag[i]))
mag_stdmed=append(mag_stdmed,median(master_dmag[i]))
写作时,会快得多:
mag_std = numpy.std(master_mag, axis=0)
mag_meg = numpy.median(master_mag, axis=0)
mag_stdmed = numpy.median(master_dmag, axis=0)