Conditional curve fit with scipy?

放肆的年华 提交于 2019-12-24 05:42:17

问题


Let's say I want to fit a straight line to my data recorded with lights off. Now I accidentally left the lights on, and my data has a constant offset from datapoint 101 and onwards.

How can I fit this? I've tried to incorporate a condition for x, but I get the error

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Remember to uncomment the remainder of the code (to encounter the error).

import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt

d1 = np.random.normal(0,0.1, 100)
d2 = np.random.normal(3,0.1, 100)

x = np.arange(0,200)
y = np.concatenate((d1,d2))

plt.plot(x, y)

# def line(x, a, b, offset):
#     if x < 101:
#         y = a * x + b
#     else:
#         y = (a * x + b) + offset
#     return y
# 
# popt, pcov = optimize.curve_fit(line, xdata = x, ydata = y)
# 
# plt.plot(x, line(x, *popt), color = "firebrick")
plt.show()

Expected output:


回答1:


I think the standard trick would be to convert boolean condition to an integer factor:

def line(x, a, b, offset):
    return (a * x + b) + offset * (x>100)



回答2:


The reason you are getting that error is that optimize is calling your line function by passing it an array of values, not just a single value. To fix this issue, your line function must me able to handle an array of values. Fortunately, numpy has a function to help you.

def line(x, a, b, offset):
    return np.piecewise(x, 
                        [x < 101, x >= 101],
                        [lambda x: a * x + b, lambda x: a * x + b + offset])

I should note that it still does not converge but that is a different issue.



来源:https://stackoverflow.com/questions/47892502/conditional-curve-fit-with-scipy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!