Итак, насколько я понимаю, у вас есть 3 точки, которым вы хотите соответствовать параболе.
Обычно проще всего просто использовать numpy.polyfit , но если выВы действительно беспокоитесь о скорости, и вы подбираете ровно три точки, нет смысла использовать подбор по методу наименьших квадратов.
Вместо этого у нас есть четная система (подгонка параболы к 3 хточки), и мы можем получить точное решение с помощью простой линейной алгебры.
Итак, в общем, вы могли бы сделать что-то вроде этого (большая часть этого представляет данные):
import numpy as np
import matplotlib.pyplot as plt
def main():
# Generate some random data
x = np.linspace(0, 10, 100)
y = np.cumsum(np.random.random(100) - 0.5)
# Just selecting these arbitrarly
left_idx, right_idx = 20, 50
# Using the mininum y-value within the arbitrary range
min_idx = np.argmin(y[left_idx:right_idx]) + left_idx
# Replace the data within the range with a fitted parabola
new_y = replace_data(x, y, left_idx, right_idx, min_idx)
# Plot the data
fig = plt.figure()
indicies = [left_idx, min_idx, right_idx]
ax1 = fig.add_subplot(2, 1, 1)
ax1.axvspan(x[left_idx], x[right_idx], facecolor='red', alpha=0.5)
ax1.plot(x, y)
ax1.plot(x[indicies], y[indicies], 'ro')
ax2 = fig.add_subplot(2, 1, 2)
ax2.axvspan(x[left_idx], x[right_idx], facecolor='red', alpha=0.5)
ax2.plot(x,new_y)
ax2.plot(x[indicies], y[indicies], 'ro')
plt.show()
def fit_parabola(x, y):
"""Fits the equation "y = ax^2 + bx + c" given exactly 3 points as two
lists or arrays of x & y coordinates"""
A = np.zeros((3,3), dtype=np.float)
A[:,0] = x**2
A[:,1] = x
A[:,2] = 1
a, b, c = np.linalg.solve(A, y)
return a, b, c
def replace_data(x, y, left_idx, right_idx, min_idx):
"""Replace the section of "y" between the indicies "left_idx" and
"right_idx" with a parabola fitted to the three x,y points represented
by "left_idx", "min_idx", and "right_idx"."""
x_fit = x[[left_idx, min_idx, right_idx]]
y_fit = y[[left_idx, min_idx, right_idx]]
a, b, c = fit_parabola(x_fit, y_fit)
new_x = x[left_idx:right_idx]
new_y = a * new_x**2 + b * new_x + c
y = y.copy() # Remove this if you want to modify y in-place
y[left_idx:right_idx] = new_y
return y
if __name__ == '__main__':
main()
Надеюсь, это немного поможет ...