我正在开发基于代理的建模项目,并且有一个代表景观的800x800网格。此网格中的每个单元格都分配了某些变量。其中一个变量是“植被”(即该细胞具有的功能类型)。我的数据名称如下:
在访问此数据框之前,会为每个单元格分配一个landscape_type。然后我循环遍历800x800网格中的每个单元格并分配更多变量,因此,例如,如果单元格1是landscape_type 4,我需要访问上面的数据框,为min和max_species_percent之间的每个functional_type生成一个随机数,并且然后将该landscape_type的所有变量(即pollen_loading,succession_time等等)分配给该单元格,但是,如果随机数的cumsum是< 100,我从下一个landscape_type中获取function_types(所以在这个例子中,我会向下移动到landscape_type 3),这一直持续到我接近100的cumsum。
我让这个过程按照需要运行,但速度非常慢 - 你可以想象,有成千上万的任务!到目前为止我这样做(self.model.veg_data是上面的df):
def create_vegetation(self, landscape_type):
if landscape_type == 4:
veg_this_patch = self.model.veg_data[self.model.veg_data['landscape_type'] <= landscape_type].copy()
else:
veg_this_patch = self.model.veg_data[self.model.veg_data['landscape_type'] >= landscape_type].copy()
veg_this_patch['veg_total'] = veg_this_patch.apply(lambda x: randint(x["min_species_percent"],
x["max_species_percent"]), axis=1)
veg_this_patch['cum_sum_veg'] = veg_this_patch.veg_total.cumsum()
veg_this_patch = veg_this_patch[veg_this_patch['cum_sum_veg'] <= 100]
self.vegetation = veg_this_patch
我确信有更有效的方法可以做到这一点。这个过程将不断重复,随着模型的进展,landscape_types会发生变化,即3变为4.所以它必不可少的变得越来越快!谢谢。
根据评论:编辑。
创建横向对象的循环如下:
for agent, x, y in self.grid.coord_iter():
# check that patch is land
if self.landscape.elevation[x,y] != -9999.0:
elevation_xy = int(self.landscape.elevation[x, y])
# calculate burn probabilities based on soil and temp
burn_s_m_p = round(2-(1/(1 + (math.exp(- (self.landscape.soil_moisture[x, y] * 3)))) * 2),4)
burn_s_t_p = round(1/(1 + (math.exp(-(self.landscape.soil_temp[x, y] * 1))) * 3), 4)
# calculate succession probabilities based on soil and temp
succ_s_m_p = round(2 - (1 / (1 + (math.exp(- (self.landscape.soil_moisture[x, y] * 0.5)))) * 2), 4)
succ_s_t_p = round(1 / (1 + (math.exp(-(self.landscape.soil_temp[x, y] * 1))) * 0.5), 4)
vegetation_typ_xy = self.landscape.vegetation[x, y]
time_colonised_xy = self.landscape.time_colonised[x, y]
is_patch_colonised_xy = self.landscape.colonised[x, y]
# populate landscape patch with values
patch = Landscape((x, y), self, elevation_xy, burn_s_m_p, burn_s_t_p, vegetation_typ_xy,
False, time_colonised_xy, is_patch_colonised_xy, succ_s_m_p, succ_s_t_p)
self.grid.place_agent(patch, (x, y))
self.schedule.add(patch)
然后,在对象本身中,我调用create_vegetation函数来添加上面df中的functional_types。此循环中的其他所有内容都来自不同的数据集,因此不相关。
答案 0 :(得分:0)
您需要在矢量化预处理步骤中提取尽可能多的计算。例如,在您的800x800循环中,您有:
burn_s_m_p = round(2-(1/(1 + (math.exp(- (self.landscape.soil_moisture[x, y] * 3)))) * 2),4)
在初始化期间执行一次,而不是执行此行800x800次:
burn_array = np.round(2-(1/(1 + (np.exp(- (self.landscape.soil_moisture * 3)))) * 2),4)
现在在你的循环中它只是:
burn_s_m_p = burn_array[x, y]
将此技术应用于其余类似的行。