У меня есть некоторые проблемы с использованием lmfit в другом процессе, чтобы сделать мой код быстрее.Как я могу определить некоторый общий ресурс, который содержит результаты каждого фитинга?
У меня есть куб данных с позициями a, b, x и f (x).Я сделал модель в lmfit , которая хорошо работает и настроил f (x) для одной точки, возвращая некоторые параметры.Lmfit возвращает класс с именем ModelResult () , который содержит каждый из этих параметров и некоторые дополнительные полезные данные.Итак, мне нужно запустить эту подгонку для каждого a и b, а затем создать куб с этими параметрами и, возможно, дополнительными данными.Я могу выполнить это линейным способом (без распараллеливания), но у меня более 1000 точек, и модель сложная, поэтому она занимает более 15000 секунд.
Моя проблема запускается при использовании многопроцессорная lib.Мне нужно обмениваться данными между каждым процессом, поэтому, когда процесс завершится, заблокируйте переменную и сохраните результаты внутри, а затем разблокируйте переменную.Многопроцессорная библиотека имеет Value () или Array () , чтобы делать то, что мне нужно.Я намеревался использовать Array и произвел некоторое изменение переменной, чтобы перейти от a и b к c, где c - диапазон a * b.Но я не могу определить массив для хранения ModelResult () для каждого c.
Вот код:
import multiprocessing as mp
import numpy as np
import time
from lmfit import Model
from numpy import sqrt, exp, pi
#Set time zero
start_time = time.time()
#Example of functions to fit
def gaussian(x, amp, cen, wid):
"""1-d gaussian: gaussian(x, amp, cen, wid)"""
return (amp / (sqrt(2*pi) * wid)) * exp(-(x-cen)**2 / (2*wid**2))
def linear(x, slope, intercept):
"""a linear function"""
return slope*x + intercept
#Function to fit every point
def fit_point(a,b,data_cube,x,pars,mod):
pos=int(b+(a*10))
data_point = np.array(data_cube[:,a,b])
#print(pos,mp.current_process().name)
error_point= np.array((data_point*0)+0.002) #Example error
res_point=mod.fit(data_point, pars, weights=1./error_point, x=x)
print(res_point.fit_report())
cube_res[pos]=res_point
return #cube_res[:]
#Invented some data
x=np.arange(10)
data_cube=np.random.rand(10, 10, 10)
#Example of a model with 2 gaussians and a line
mod = Model(linear, prefix='l_')+Model(gaussian, prefix='g1_')+Model(gaussian, prefix='g2_')
pars= mod.make_params()
pars['g1_amp'].set(0.5)
pars['g2_amp'].set(0.5)
pars['g1_cen'].set(2)
pars['g2_cen'].set(3)
pars['g1_wid'].set(0.5)
pars['g2_wid'].set(0.5)
pars['l_slope'].set(1)
pars['l_intercept'].set(1)
#Definition of the shared Array #Where I think there is the problem!
cube_res = mp.Array('u', 100)
#Definition of the process and starts
processes = []
for a in np.arange(0,10):
for b in np.arange(0,10):
process = mp.Process(target=fit_point, args=(a,b,data_cube,x,pars,mod))
process.start()
processes.append(process)
for process in processes:
process.join()
print('Time count')
print("--- %s seconds ---" % (time.time() - start_time))
#Intent to print some results
#print(cube_res[20].fit_report)
#Final, to recover a,b
#final_cube_res = np.reshape(cube_res, (100,100))
Ошибки:
TypeError: unicode string expected instead of ModelResult instance
Это потому, что я определяю mp.Array ('u', 100) , где 'u' - это юникод, а 100 - диапазон.
Я не знаю, как определить массив, чтобы можно было сохранить ModelResult внутри.
Спасибо за чтение!