Интерполируйте временные ряды, выберите значение y из x - PullRequest
0 голосов
/ 29 мая 2018

Я некоторое время искал ответ на этот вопрос и приблизился, но продолжаю сталкиваться с ошибками.Есть много подобных вопросов, которые почти отвечают на это, но я не смог решить их.Любая помощь или точка в правильном направлении приветствуется.

У меня есть график, показывающий температуру как в основном нелинейную функцию глубины, со значениями 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

Я хотел бы найти значение y при конкретном значении x 22,61, которое не является одним из исходных значений температуры в наборе данных.Я пробовал следующие шаги:

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]

, но это возвращает значения y для определенного, уже перечисленного значения x, а не для интерполированного значения.

Надеюсь, это достаточно ясно.Я новичок в науке о данных и в стеке потока, поэтому, если мне нужно перефразировать вопрос, пожалуйста, дайте мне знать.

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Вы действительно можете использовать функцию numpy.interp.Как указано в документации

Х-координаты точек данных должны увеличиваться [...]

Таким образом, вам нужно отсортировать массивы в массиве 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

0 голосов
/ 29 мая 2018

Я думаю, 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.   ])

Вы также можете выбрать несколько других нелинейных интерполяций (квадратичные, куб и тд).Посмотрите подробную документацию по интерполяции для получения более подробной информации.

[Редактировать] : вам нужно будет отсортировать массивы по оси x при добавлении @ImportanceOfBeingErnest.

...