想象一下,我们有一个带有离散点的3D网格。 3维(包括间隔终点)的范围是:
in x:[4000,7000],步长1000,y:[0.0,2.0],步长1.0,z:[ - 0.75,0.75],步长0.25
现在应该对[4000,7000,100],[0.0,2.0,0.1],[ - 0.75,0.75,0.05]范围内的所有点进行以下任务(大约20000 = 31 * 21 * 31点) ):
找到包含该点的最小立方体。但是网格中有漏洞(每个点应该有一个"物理"对应物作为文件,但有些没有)。我尝试了以下非常简单的代码(我称之为cuboid' cube'):
def findcubesnew(startvalues, endvalues, resols, \
loopvalues, refvalues, modelpath):
cubearray = []
startvalue1 = startvalues[0]
endvalue1 = endvalues[0]
resol1 = resols[0]
refvalue1 = refvalues[0]
loopstop1 = loopvalues[0][0]
loopstart1 = loopvalues[1][0]
startvalue2 = startvalues[1]
endvalue2 = endvalues[1]
resol2 = resols[1]
refvalue2 = refvalues[1]
loopstop2 = loopvalues[0][1]
loopstart2 = loopvalues[1][1]
startvalue3 = startvalues[2]
endvalue3 = endvalues[2]
resol3 = resols[2]
refvalue3 = refvalues[2]
loopstop3 = loopvalues[0][2]
loopstart3 = loopvalues[1][2]
refmass = refvalues[3]
refveloc = refvalues[4]
for start1 in numpy.arange(startvalue1, loopstop1 + resol1, resol1):
for end1 in numpy.arange(loopstart1, endvalue1 + resol1, resol1):
for start2 in numpy.arange(startvalue2, loopstop2 + resol2, resol2):
for end2 in numpy.arange(loopstart2, endvalue2 + resol2, resol2):
for start3 in numpy.arange(startvalue3, loopstop3 + resol3, resol3):
for end3 in numpy.arange(loopstart3, endvalue3 + resol3, resol3):
if glob.glob(*start1*start2*start3) and \
if glob.glob(modelpath/*start1*start2*end3) and \
if glob.glob(modelpath/*start1*end2*start3) and \
if glob.glob(modelpath/*start1*end2*end3) and \
if glob.glob(modelpath/*end1*start2*start3) and \
if glob.glob(modelpath/*end1*start2*end3) and \
if glob.glob(modelpath/*end1*end2*start3) and \
if glob.glob(modelpath/*end1*end2*end3):
cubearray.append((start1, end1, start2, end2, start3, end3))
else:
pass
return cubearray
foundcubearray = findcubesnew([metalstart, tempstart, loggstart], \
[metalend, tempend, loggend], [metalresol, tempresol, loggresol], \
looplimitarray, [refmetal, reftemp, reflogg, refmass, refveloc], \
modelpath)
if foundcubearray:
bestcube = findsmallestcubenew(foundcubearray, \
[metalresol, tempresol, loggresol])
....
因此,我进入x方向的循环,从下网格边界到我们想要获得长方体的所需点下方的最大值,以及从该点之后的最小值到更高网格边界的另一个循环。类似地,对于y方向和z方向,并且环彼此嵌套。 if部分是没有格式字符串等的伪代码,并检查所有具有这些值的文件(以及其他数量可能在文件名中也是如此)确实存在(存在长方体的所有角落)。
如果点的一个或多个坐标与网格中的值一致,此代码也会找到点或线或矩形,但它不是问题(实际上是期望的)。
这里的瓶颈是寻找长方体需要相当长的时间(最小的长方体可以很容易和快速地找到,如果有多个具有相同(最小)的尺寸,我不在乎选择哪一个)。另外,我需要读入网格的开始和结束值,步长,我的点的参考值(坐标)和一些其他变量。有什么方法可以优化代码?每点大约需要1.4秒,所以~20000点大约需要8小时,这太长了。
我知道如果我找到了最小的长方体,例如对于点4500,0.5,0.1,我可以立即告诉多维数据集内的所有其他点有限制[4000,5000; 0.0,1.0; 0,0.25]具有相同的最小长方体。我仍然对一个优化所有20000次运行的计算时间的解决方案感兴趣。这个应用是恒星模型的插值程序,其中需要在插值点周围具有长方体形状的8个网格点。
P.S。:我希望延续线断裂和缩进是正确的。在我的代码中它们不存在,虽然每行超过80个字符并不是一个好的风格:)。
答案 0 :(得分:0)
我的建议是不要使用glob。如果我正确读取数字,那么modelpath目录最多可包含20,000个文件,并且内部循环体中可能有8个globs。我很惊讶每点只需要1.4秒!
文件名只是用作布尔值,对吧?重要的是文件是否存在。
我会创建一个与3D网格尺寸相同的布尔三维数组,初始化为False。然后读取目录的内容,将每个文件名转换为3D索引并将其设置为True。
然后使用布尔数组搜索点,而不是文件系统。
希望这有帮助。