Как я могу ускорить присвоение numpy значений массива для объектов (агентов) в Mesa - PullRequest
0 голосов
/ 08 апреля 2020

Я использую mesa (агентное моделирование) для реализации модели ландшафта. Для создания ландшафта я использую несколько массивов numpy (800 x 800), каждый из которых содержит информацию c (например, высота, влажность почвы и др. c и c). Чтобы инициализировать модель, Mesa выполняет итерацию по указанному пользователем размеру сетки (в данном случае 800 x 800) и назначает «агенты» для каждого «патча» в сетке:

    def coord_iter(self):
    """ An iterator that returns coordinates as well as cell contents. """
    for row in range(self.width):
        for col in range(self.height):
            yield self.grid[row][col], row, col  # agent, x, y

Затем с помощью этого итератора I присвойте значения из массивов numpy каждому x, y в сетке:

for agent, x, y in self.grid.coord_iter(self.landscape.elevation):
        # check that patch is land
        if self.landscape.elevation[x, y] != -9999:
            self.agents_created += 1
            self.create_landscape_patch(x, y)

            # set landscape_classes (i.e. 0 = bracken) if 5 then this is a deposition area
            if self.landscape.vegetation[x, y] != 5:
                self.create_vegetation_patch(x, y)

            # populate landscape patch with values
            self.add_landscape_patch(x, y)

        # if deposition site
        if self.landscape.vegetation[x, y] == 5:
            self.create_deposition_patch(x,y)

В массиве numpy есть некоторые значения x, y, которые мне не нужно присваивать сетке поэтому в настоящее время я использую простой оператор if для фильтрации этих значений (if self.landscape.elevation[x, y] != -9999:). Ясно, что с помощью функцииordin_iter я неизбежно выполняю l oop 800 x 800 раз, когда я могу избежать итерации, когда значения в массиве numpy == -9999. Пример того, как каждый «агент» создается и затем назначается мезасети, приведен ниже (альбомный патч).

def create_landscape_patch(self, x, y):

    self.elevation_xy = int(self.landscape.elevation[x, y])

    # calculate burn probabilities based on soil and temp
    self.burn_s_m_p = self.landscape.burn_s_m_p_array[x, y]
    self.burn_s_t_p = self.landscape.burn_s_t_p_array[x, y]

    # calculate succession probabilities based on soil and temp
    self.succ_s_m_p = self.landscape.succ_s_m_p_array[x, y]
    self.succ_s_t_p = self.landscape.succ_s_t_p_array[x, y]

    self.time_colonised_xy = self.landscape.time_colonised[x, y]
    self.is_patch_colonised_xy = self.landscape.colonised[x, y]

def add_landscape_patch(self, x, y):
    patch = Landscape(self.unique_id, (x, y), self, self.elevation_xy, self.burn_s_m_p, self.burn_s_t_p, self.vegetation_typ_xy,
                      False, self.time_colonised_xy, self.is_patch_colonised_xy, self.succ_s_m_p, self.succ_s_t_p, self.veg_this_patch)
    self.grid.place_agent(patch, (x, y))
    self.schedule.add(patch)
    self.unique_id += 1

В настоящее время мой код работает, но я знаю, что должен быть более эффективный способ достичь этого результата. «Построение» ландшафта занимает несколько минут, и я надеюсь построить несколько тысяч! Любая помощь в том, как я могу сделать это более эффективным, будет высоко ценится. Спасибо

...