问题
I have a question about a simple fit function in Python. I am trying to fit two different functions on a data set and the border between the two regimes should be also a fit parameter. Very naively I was trying something like this:
def FitFunc(x, a, b, c, d, e, border):
if x < border:
return a * x + b
if x > border:
return c * x**2 + d * x + e
But I got a ValueError:
The truth value of a Series is ambiguous. Use a.empty(), a.bool(), a.item(), a.any() or a.all()
I understand that you can not compare my x array to an integer value (which is not even assigned to a fixed value, this should be done by the curve_fit procedure).
I was not able to find a solution for this supposedly simple problem. Can someone help me out of this?
Thanks in advance!
EDIT: I constructed an example: For the data with x<5 this is perfectly described by a linear function (y=x-3), For x>5 this is perfectly described by a square function (y=x**2/5-3*x/5). Assume you don't know that x is the perfect 'border', is there a way to let curve_fit find out?
回答1:
The error message is saying that comparing the values of an array (x
) with a scalar value (border
) is ambiguous. Do you mean if any values of x
are less than border
or if all values of x
are less than border
?
I suspect that what you really want is numpy's where
function, which is sort of like looping over x
and deciding which expression to use point-by-point, only much faster:
def FitFunc(x, a, b, c, d, e, border):
out = a * x + b
out[np.where(x > border)] = c * x**2 + d * x + e
return out
I think that is what you want, and it should work to select the proper functional form based on border
.
However, I would caution that it may not do what you want. That is, it looks like you intend border
to be a fitting variable.
Fitting variables in scipy optimize
routines (and most "curve fitting" contexts) need to be continuous floating point variables. Your border
variable would be used as a discrete, integer value for the index of x
to change functional form. The fitting algorithm will first choose a value (let's say 5.0), then make a very small change in that value (to, say, 5.0000002). That will not change where the breakpoint between your two functional forms is, and the fit will decide that border
does not change the fit. I wish I knew a way around this.
来源:https://stackoverflow.com/questions/49997412/fit-of-two-different-functions-with-boarder-as-fit-parameter