scipy:插值,立方和&线性

时间:2015-06-18 10:34:30

标签: python scipy interpolation

我试图插入我的数据集(第一个是时间,第三个是实际数据):

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

data = np.genfromtxt("data.csv", delimiter=" ")

x = data[:, 0]
y = data[:, 2]

xx = np.linspace(x.min(), x.max(), 1000)
y_smooth = interp1d(x, y)(xx)
#y_smooth = interp1d(x, y, kind="cubic")(xx)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xx, y_smooth, "r-")

plt.show()

但我看到线性和三次插值之间存在一些奇怪的差异。 这是线性的结果: enter image description here

以下是立方体相同的: enter image description here

我不确定,为什么图表一直在跳跃且y_smooth包含不正确的值?

ipdb> y_smooth_linear.max()
141.5481144
ipdb> y_smooth_cubic.max()
1.2663431888584225e+18

有人可以向我解释,如何更改我的代码以实现正确的插值?

UPD :此处为data.cvs file

2 个答案:

答案 0 :(得分:4)

您的数据包含相同x值的多个y值。这违反了大多数插值算法的假设。

丢弃具有重复x值的行,平均每个x的y值,或者获得x值的更好分辨率,使它们不再相同。

答案 1 :(得分:2)

鉴于x np.unique有重复值,您可以使用y 为每个x选择x2, idx = np.unique(x, return_index=True) y2 = y[idx] 的唯一值:

return_index=True

x2会导致cfh's observation不仅返回唯一值idx,还会返回其中唯一x的位置x原始y数组。请注意,这会为每个唯一x选择y第一个值。

如果您想平均每个唯一x的所有import scipy.stats as stats x2, inv = np.unique(x, return_inverse=True) y2, bin_edges, binnumber = stats.binned_statistic( x=inv, values=y, statistic='mean', bins=inv.max()+1) 值,您可以使用 np.unique

return_inverse=True

np.unique告诉binned_statistic返回索引 原始数组可以重建。这些指数也可以作为分类 标签或“因素”,它们是如何在呼叫中使用的 上面import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import interp1d import scipy.stats as stats data = np.genfromtxt("data.csv", delimiter=" ") x = data[:, 0] y = data[:, 1] x2, idx, inv = np.unique(x, return_index=True, return_inverse=True) y_uniq = y[idx] y_ave, bin_edges, binnumber = stats.binned_statistic( x=inv, values=y, statistic='mean', bins=inv.max()+1) xx = np.linspace(x.min(), x.max(), 1000) y_smooth = interp1d(x, y)(xx) y_smooth2 = interp1d(x2, y_uniq, kind="cubic")(xx) y_smooth3 = interp1d(x2, y_ave, kind="cubic")(xx) fig, ax = plt.subplots(nrows=3, sharex=True) ax[0].plot(xx, y_smooth, "r-", label='linear') ax[1].plot(xx, y_smooth2, "b-", label='cubic (first y)') ax[2].plot(xx, y_smooth3, "b-", label='cubic (ave y)') ax[0].legend(loc='best') ax[1].legend(loc='best') ax[2].legend(loc='best') plt.show()

set_over

enter image description here