插值时间序列,从x中选择y值

时间:2018-05-29 11:35:56

标签: python matplotlib interpolation

我一直在寻找这个问题的答案,并且已经接近但仍然遇到错误。有很多类似的问题几乎可以解决这个问题,但我无法解决它。任何帮助或正确方向的观点都值得赞赏。

我有一个图表,显示温度是深度的主要非线性函数,x和y值是从pandas数据框中提取的。

import matplotlib.pyplot as plt

x = (22.81,  22.81,  22.78,  22.71,  22.55,  22.54,  22.51,  22.37)
y = (5, 16, 23, 34, 61, 68, 77, 86)

#Plot details
plt.figure(figsize=(10,7)), plt.plot(style='.-')
plt.title("Temperature as a Function of Depth")
plt.xlabel("Temperature"), plt.ylabel("Depth")
plt.gca().invert_yaxis()
plt.plot(x,y, linestyle='--', marker='o', color='b')

这给了我一个像这样的图像(注意翻转的y轴,因为我说的是深度):

enter image description here

我想在特定的x值22.61处找到y值,这不是数据集中的原始温度值之一。我尝试了以下步骤:

np.interp(22.61, x1, y1)

这给了我一个我知道不正确的值,就像

一样
s = pd.Series([5,16,23,34,np.nan,61,68,77,86], index=[22.81,22.81,22.78,22.71,22.61,22.55,22.54,22.51,22.37])
s.interpolate(method='index')

我试图设置一个框架并强制插值。我也试过

line = plt.plot(x,y)
xvalues = line[0].get_xdata()
yvalues = line[0].get_ydata()
idx = np.where(xvalues==xvalues[3]) ## 3 is the position
yvalues[idx]

但是这会返回特定的已列出的x值的y值,而不是插值的值。

我希望这很清楚。我是数据科学和stackoverflow的新手,所以如果我需要重新解释这个问题,请告诉我。

2 个答案:

答案 0 :(得分:3)

您确实可以使用numpy.interp功能。正如文档所述

  

数据点的x坐标必须增加[...]

因此,在使用此函数之前,需要对x数组上的数组进行排序。

# Sort arrays
xs = np.sort(x)
ys = np.array(y)[np.argsort(x)]

# x coordinate
x0 = 22.61
# interpolated y coordinate
y0 = np.interp(x0, xs, ys)

<小时/> 完整代码:

import numpy as np
import matplotlib.pyplot as plt

x = (22.81,  22.81,  22.78,  22.71,  22.55,  22.54,  22.51,  22.37)
y = (5, 16, 23, 34, 61, 68, 77, 86)

# Sort arrays
xs = np.sort(x)
ys = np.array(y)[np.argsort(x)]

# x coordinate
x0 = 22.61
# interpolated y coordinate
y0 = np.interp(x0, xs, ys)

#Plot details
plt.figure(figsize=(10,7)), plt.plot(style='.-')
plt.title("Temperature as a Function of Depth")
plt.xlabel("Temperature"), plt.ylabel("Depth")
plt.gca().invert_yaxis()
plt.plot(x,y, linestyle='--', marker='o', color='b')
plt.plot(x0,y0, marker="o", color="C3")

enter image description here

答案 1 :(得分:2)

我认为Scipy提供了一个更直观的API来解决这个问题。然后,您可以轻松地继续使用Pandas中的数据。

from scipy.interpolate import interp1d
x = np.array((22.81,  22.81,  22.78,  22.71,  22.55,  22.54,  22.51,  22.37))
y = np.array((5, 16, 23, 34, 61, 68, 77, 86))

# fit the interpolation on the original index and values
f = interp1d(x, y, kind='linear')

# perform interpolation for values across the full desired index
f([22.81,22.81,22.78,22.71,22.61,22.55,22.54,22.51,22.37])

<强>输出:

array([16.   , 16.   , 23.   , 34.   , 50.875, 61.   , 68.   , 77.   ,
   86.   ])

您也可以选择多个其他非线性插值(二次,三次等)。有关更多详细信息,请查看全面的interpolation documentation

[编辑] :当@ImportanceOfBeingErnest添加时,您需要在x轴上对数组进行排序。