在python中创建增量平滑样条曲线而不是非均匀增量

kpbpu008  于 2023-01-24  发布在  Python
关注(0)|答案(2)|浏览(137)

我尝试使用样条曲线平滑我的数据-基本上是y轴上的累积百分比和x轴上的参考点。我得到了大部分正确的,但是,我面临的挑战是我的y轴是以非线性的方式增加-如下面的样条曲线图所示-y轴值不断增加和减少,而不仅仅是增加。
我仍然希望曲线平滑,但希望y轴随x轴增加,即每个后续y轴点的值应等于或略高于前一个值,而不是先增加后减少。
可复制代码:

import pandas as pd 
import numpy as np 
from scipy.interpolate import make_interp_spline 
import matplotlib.pyplot as plt 
from matplotlib.pyplot import figure 

percentile_block_df = pd.DataFrame({ 
'x' : [0.5,100.5,200.5,400.5,800.5,900.5,1000.5], 
'percentile' : [0.0001,0.01,0.065,0.85,0.99,0.9973,0.9999] 
})

figure(figsize=(8, 6), dpi=80) 
y = percentile_block_df.percentile 
x = percentile_block_df.x 

X_Y_Spline = make_interp_spline(x, y) 

# Returns evenly spaced numbers 
# over a specified interval. 
X_ = np.linspace(x.min(), x.max(), 1000)
Y_ = X_Y_Spline(X_)

figure(figsize=(18, 6), dpi=80)
plt.subplot(1, 2, 1) # row 1, col 2 index 1
plt.plot(x, y,"ro")
plt.plot(x, y)
plt.title("Original")
plt.xlabel('X')
plt.ylabel('Percentile ')

plt.subplot(1, 2, 2) # index 2
plt.plot(x, y,"ro")
plt.plot(X_, Y_,"green")
plt.title("Spline Plot")
plt.xlabel('X')
plt.ylabel('Percentile ')

plt.show()

cnh2zyt3

cnh2zyt31#

你要找的是“单调性保持插值”。快速搜索一下就会发现scipy.interpolate.PchipInterpolator正好做到了这一点。下面是你的例子在简单地插入from scipy.interpolate import PchipInterpolator而不是from scipy.interpolate import make_interp_spline时的结果。

当然,这是否合适取决于您对插值的具体要求。我鼓励您研究其他选项。
类似问题:

46qrfjad

46qrfjad2#

最终对我有效的代码:
此链接解释了单调三次插值的必要性

#this code allows "smoothening" of the data
B_spline_coeff1 = PchipInterpolator(x1, np.log(y1))
X1_Final = np.linspace(x.min(), x.max(), 1000)
Y1_Final = np.exp(B_spline_coeff1(X1_Final))

#plot subplots
figure(figsize=(18, 6), dpi=80)
plt.subplot(1, 2, 1) # row 1, col 2 index 1
plt.plot(x, y,"ro")
plt.plot(x, y)
plt.title("Original")
plt.xlabel('X')
plt.ylabel('Percentile ')

plt.subplot(1, 2, 2) # index 2
plt.plot(x, y,"ro")
plt.plot(X1_Final, Y1_Final,"green")
plt.title("Spline Plot")
plt.xlabel('X')
plt.ylabel('Percentile ')

plt.show()

相关问题