Оптимизация скорости с помощью функции map () - PullRequest
0 голосов
/ 30 октября 2018

Итак, у меня есть проект, в котором я должен имитировать изображение высокого разрешения через спутниковое изображение. Я делаю это с Python, и у меня есть программа, которая работает - НО, это занимает 3 минуты, чтобы имитировать типичный размер изображения (1200 на 1500 пикселей). Я проверял код на время и обнаружил, что это самая трудоемкая часть сценария, которая занимает 3 минуты (остальная часть кода занимает еще около 10 секунд).

Вот та часть кода:

def weight_values(Pix_center,row_0,row_1,col_0,col_1,t_row_0,t_row_1,t_col_0,t_col_1):
    foot_in_truth = foots[Pix_center,row_0:row_1,col_0:col_1]
    truth_in_foot = truth[t_row_0:t_row_1, t_col_0:t_col_1]
    weighted_vals = (foot_in_truth*truth_in_foot).sum()/foot_in_truth.sum()
    return weighted_vals

no_mask = np.where(np.ma.getmaskarray(Pix_centers) == False)
weighted_mean = np.array(map(weight_values, (Pix_centers[no_mask]),(row0[no_mask]),(row1[no_mask]),(col0[no_mask]),(col1[no_mask]),(truth_row0[no_mask]),(truth_row1[no_mask]),(truth_col0[no_mask]),(truth_col1[no_mask])))

В приведенном выше примере моя функция weight_values ​​ принимает множество значений. И когда они вызываются с использованием map , все эти итерируемые объекты являются одномерными объектами одинакового размера.

Вот краткое описание задействованных массивов:

  • foots: трехмерный массив с номером пикселя размеров, вдоль дорожки и поперек дорожки (последние две нелокализованы, то есть центрированы в 0). Это представляет след спутника в каждом пикселе. Фактически, это занимает площадь, которая фактически находится внутри каждого пикселя - я использую инструмент с большой полосой, поэтому это важно.
  • правда: это то, что я моделирую. Он имеет то же разрешение, что и футы, но покрывает определенную область по координатам вдоль и поперек пути

1D-массивы, вызываемые в функции карты как итерируемые, имеют маскированные значения, поэтому используется no_mask. Эти массивы имеют максимальное значение 1800000 (количество пикселей изображения), но мой код позволяет мне выбирать меньшие сегменты для тестирования.

Этот подход работает! Но мне было интересно, есть ли способ ускорить его. До сих пор я пытался с настройкой карты / лямбды (которая была почти в два раза медленнее), пониманием списка и циклом for. Пока что этот подход является самым быстрым среди всей моей выборки в 1,8 миллиона пикселей. Пожалуйста, дайте мне знать, если у вас есть идеи, как это ускорить. Я бы разместил здесь весь код, но большая его часть не имеет значения, плюс он использует файлы на моей локальной машине, которые я не уверен, что у меня есть разрешение на передачу.

Также дайте мне знать, если что-то здесь неясно или вы не понимаете вопрос, и я сделаю все возможное, чтобы сделать его более читабельным.

1 Ответ

0 голосов
/ 30 октября 2018

Я быстро рассмотрел вашу функцию weight_value, которая выполняет усреднение для каждого пикселя, и у каждого пикселя есть много соседей. Поэтому каждый соседний пиксель читается много раз. Это выполняется за O (n ^ 3) времени. Обычная, более быстрая техника - совокупная сумма. Вы можете начать с этого примера , хотя он находится в Matlab. Идея такая же в питоне. Цель состоит в том, что вам нужно вычислить значение каждого пикселя только один раз. Версия Python здесь .

...