我正在编写一个程序,可以创建温度的直观表示。在网格中有200个数据点,我使用插值来填充这些点之间的像素。
我编写了一个程序,使用反距离权重(在本例中为修改后的Shepards方法)输出我想要的数据,给出如下所示的图像:
heatmap http://img688.imageshack.us/img688/1069/stackoverflowimage.png
随着所有不相关的东西被删除(例如图像库的东西),创建它的代码如下所示:
首先计算从每个点到每个管的所有距离和总距离(因为它们是不变的)。在这一点上,我并不特别担心所花费的时间,因为它只执行一次,但我包含了代码,因此您可以看到值的存储方式。
#set_tubes creates an array of tubes (which is the data I'm working on)
#each tube has an x position in pixels, a y position in pixels and a temperature
self.set_tubes()
self.dists = []
for x in range(1,BASE_WIDTH-1):
self.summed_dists.append([])
self.dists.append([])
for y in range(1,BASE_HEIGHT-1):
self.summed_dists[x-1].append([])
self.dists[x-1].append([])
self.summed_dists[x-1][y-1]=0
for row in range(10):
self.dists[x-1][y-1].append([])
for tube in range(20):
dist = np.sqrt((x-self.tubes[row][tube].xPos)**2+(y-self.tubes[row][tube].yPos)**2)+0.1
#The -3 in the next two lines is simply a weighting factor
self.dists[x-1][y-1][row].append(dist**(-3))
self.summed_dists[x-1][y-1] = self.summed_dists[x-1][y-1] + dist**(-3)
然后进行插值(这在温度变化时重复进行)。这就是重要的时间。
def other_proc_calc_temp(ret_queue, dists, tubes,summed_dists):
heat_values = list()
for x in range (BASE_WIDTH):
heat_values.append([])
for y in range(BASE_HEIGHT):
summed = 0
for row in range(10):
for tube in range(20):
dist = dists[x][y][row][tube]
temp = tubes[row][tube].temp
summed = summed + temp* dist/summed_dists[x-1][y-1]
heat_values[x].append(summed)
我的问题在于速度,对于200 * 200像素的图像,这需要大约30秒才能在我的计算机上运行代码的第二部分。是否有更快的方法来获得相同或类似的效果,或者在我的代码中出现某种明显的低效率?
我尝试了双线性和双三次插值,但对我得到的图像并不是特别满意。
我还限制了影响单个像素的数据点的邻域,以试图加速它,这确实有所帮助,但我想我尽可能地推动了它,而不会在图像中造成明显的线条。
感谢您提供任何帮助。
答案 0 :(得分:1)
可能有一项改进:
尝试将dists[x][y]
和tubes[row]
移到最里面的循环之外。
这个可能每个内部迭代取出几个数组索引查找(它
取决于Python解释器的聪明程度):
def other_proc_calc_temp(ret_queue, dists, tubes,summed_dists):
heat_values = list()
for x in range (BASE_WIDTH):
heat_values.append([])
for y in range(BASE_HEIGHT):
outer_dist = dists[x][y]
summed = 0
for row in range(10):
inner_dist = outer_dist[row]
inner_tube = tubes[row]
for tube in range(20):
dist = inner_dist[tube]
temp = inner_tubes[tube].temp
summed = summed + temp* dist/summed_dists[x-1][y-1]
heat_values[x].append(summed)
如果Python解释器足够聪明,可以知道值没有 改变了,这更难阅读。但如果是Python解释器 一遍又一遍地重新计算所有这些数组索引,它可以加起来。
我以前在这里有一个关于设置数组大小而不是用.append()
增长它们的段落。 gnibbler says .append()
is an O(1) amortized operation这意味着这里可能的优化很少。如果您对我写的内容感到好奇,请参阅编辑历史记录。