Я пытаюсь сделать gaussian подходящий для многих точек данных. Например. Я имею массив данных 256 x 262144. Если 256 точек нужно установить на гауссовское распределение, и мне нужно 262144 из них.
Иногда пик гауссовского распространения выходит за пределы диапазона данных, поэтому наилучшим подходом является получение точной кривой соответствия результатов. Даже если пик находится внутри диапазона, кривая-фитинг дает лучшую сигму, потому что другие данные не находятся в диапазоне.
У меня это работает для одной точки данных, используя код http://www.scipy.org/Cookbook/FittingData.
Я попытался просто повторить этот алгоритм, но похоже, что для его решения потребуется порядка 43 минут. Есть ли уже написанный быстрый способ сделать это параллельно или более эффективно?
from scipy import optimize
from numpy import *
import numpy
# Fitting code taken from: http://www.scipy.org/Cookbook/FittingData
class Parameter:
def __init__(self, value):
self.value = value
def set(self, value):
self.value = value
def __call__(self):
return self.value
def fit(function, parameters, y, x = None):
def f(params):
i = 0
for p in parameters:
p.set(params[i])
i += 1
return y - function(x)
if x is None: x = arange(y.shape[0])
p = [param() for param in parameters]
optimize.leastsq(f, p)
def nd_fit(function, parameters, y, x = None, axis=0):
"""
Tries to an n-dimensional array to the data as though each point is a new dataset valid across the appropriate axis.
"""
y = y.swapaxes(0, axis)
shape = y.shape
axis_of_interest_len = shape[0]
prod = numpy.array(shape[1:]).prod()
y = y.reshape(axis_of_interest_len, prod)
params = numpy.zeros([len(parameters), prod])
for i in range(prod):
print "at %d of %d"%(i, prod)
fit(function, parameters, y[:,i], x)
for p in range(len(parameters)):
params[p, i] = parameters[p]()
shape[0] = len(parameters)
params = params.reshape(shape)
return params
Обратите внимание, что данные не обязательно 256x262144, и я сделал некоторые fudging в nd_fit, чтобы сделать эту работу.
Код, который я использую, чтобы заставить его работать,
from curve_fitting import *
import numpy
frames = numpy.load("data.npy")
y = frames[:,0,0,20,40]
x = range(0, 512, 2)
mu = Parameter(x[argmax(y)])
height = Parameter(max(y))
sigma = Parameter(50)
def f(x): return height() * exp (-((x - mu()) / sigma()) ** 2)
ls_data = nd_fit(f, [mu, sigma, height], frames, x, 0)
Примечание. Решение, размещенное ниже @JoeKington, великолепно и эффективно решает. Однако он не работает, если значительная область гауссова находится внутри соответствующей области. Мне нужно будет проверить, действительно ли среднее значение остается точным, поскольку это главное, для чего я это использую.