в качестве демонстрации использования многопроцессорной обработки и разницы в векторизации по сравнению с нет, мы можем начать с определения / извлечения общего кода:
from multiprocessing import Pool
import numpy as np
def add_two_numbers(x,y):
return x+y
# use a large number of values so processing takes some measurable amount of time
values = np.arange(3001)
тогда мы можем сделать вашу наивную вещь:
result = np.empty([len(values)]*2, values.dtype)
for i, x in enumerate(values):
for j, y in enumerate(values):
result[i,j] = add_two_numbers(x, y)
, что занимает ~ 3,5 секунды на моем ноутбуке. затем мы можем переместить это к использованию multiprocessing
Pool
с:
def process_row(x):
output = np.empty_like(values)
for i, y in enumerate(values):
output[i] = add_two_numbers(x, y)
return output
with Pool() as pool:
result = np.array(pool.map(process_row, values))
, что занимает у меня около 1 секунды, затем мы можем векторизовать это в Pool
с помощью:
def process_row_vec(x):
return add_two_numbers(values, x)
with Pool() as pool:
result = np.array(pool.map(process_row_vec, values))
, что занимает 0,25 секунды, и, наконец, мы можем использовать полностью векторизованную версию numpy:
x, y = np.meshgrid(values, values)
result = add_two_numbers(x, y)
, что занимает ~ 0,09 секунды (90 мс). Я также понял, что при работе с таким большим количеством элементов эти промежуточные массивы (x
и y
) занимают значительное количество времени вычислений, и векторизация по строкам происходит быстрее:
result = np.empty([len(values)]*2, values.dtype)
for i, x in enumerate(values):
result[i,:] = add_two_numbers(x, values)
занимает 0,05 секунды (50 мс).
надеюсь, что эти примеры дадут вам некоторые идеи о том, как реализовать ваш алгоритм!