У меня есть многомерный массив, который нужно вычислить с помощью импортированной функции. (Я использую блокнот jupyter, поэтому я экспортировал функцию в ipynb и снова импортировал ее). Функция принимает в качестве аргумента одномерный массив.
#Function
def calculatespi(datagrid,q):
date_time = datagrid['time'][:]
gridvalue = datagrid.values
if np.isnan(np.sum(gridvalue)) != True:
df_precip = pd.DataFrame({"Date": date_time,"precip":gridvalue})
spi_prc = spi.SPI()
spi3_grid = spi_prc.calculate(df_precip, 'Date', 'precip', freq = 'M', scale = 3, fit_type = "lmom", dist_type = "gam")
spi3 = spi3_grid['precip_scale_3_calculated_index'].values
else:
spi3 = np.empty((489))
spi3[:] = np.nan
q.put(spi3)
#Main Notebook
if name == "main":
spipi = []
processes = []
for x in range (3):
for y in range(3):
q = multiprocessing.Queue()
p = multiprocessing.Process(target=calculatespi, args= (prcoba[:,x,y],q))
p.start()
processes.append(p)
spipi.append(q.get())
for process in processes:
process.join()
После сотен попыток, наконец, я могу получить результаты своей проблемы, но это заняло больше времени, чем запуск без использования многопроцессорной обработки. Что я должен делать?
куда мне его потом положить? или я использую неправильный метод? у вас есть предложения, сэр?
Использование concurrent.futures.ProcessPoolExecutor
значительно упрощает задачу.
Сначала замените в calculatespi
q.put(spi3)
на return spi3
и удалите параметр q
. Тогда «основной» код можно записать как
#Main Notebook
if name == "main":
from concurrent.futures import ProcessPoolExecutor
args = []
for x in range (3):
for y in range(3):
args.append(prcoba[:,x,y])
with ProcessPoolExecutor() as executor:
spipi = list(executor.map(calculatespi, args))
Обо всем остальном позаботится исполнитель.
Вызов "q.get()" блокируется до тех пор, пока "calculatespi" не поместит результат в очередь.