Pandas Series.Shift усекает последнее значение

На самом деле вы можете использовать scipy.interpolate.inter1d для этого.

В качестве быстрого примера с квадратом:

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

x = [0, 1, 1, 0, 0]
y = [0, 0, 1, 1, 0]

t = np.arange(len(x))
ti = np.linspace(0, t.max(), 10 * t.size)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here [/g0] enter image description here enter image description here / g5]

Однако, как вы можете видеть, это приводит к некоторым проблемам на 0,0.

Это происходит потому, что сегмент сплайна зависит не только от двух точек. Первая и последняя точки не «связаны» в том, как мы интерполировали. Мы можем исправить это путем «заполнения» последовательностей x и y со вторыми и последними и вторыми точками, так что существуют граничные условия «обматывания» для сплайна на конечных точках.

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

x = [0, 1, 1, 0, 0]
y = [0, 0, 1, 1, 0]

# Pad the x and y series so it "wraps around".
# Note that if x and y are numpy arrays, you'll need to
# use np.r_ or np.concatenate instead of addition!
orig_len = len(x)
x = x[-3:-1] + x + x[1:3]
y = y[-3:-1] + y + y[1:3]

t = np.arange(len(x))
ti = np.linspace(2, orig_len + 1, 10 * orig_len)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here [/g1]

И просто чтобы показать, как это выглядит с вашими данными:

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

x = [-0.25, -0.625, -0.125, -1.25, -1.125, -1.25,
     0.875, 1.0, 1.0, 0.5, 1.0, 0.625, -0.25]
y = [1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 1.875,
     1.75, 1.625, 1.5, 1.375, 1.25, 1.25]

# Pad the x and y series so it "wraps around".
# Note that if x and y are numpy arrays, you'll need to
# use np.r_ or np.concatenate instead of addition!
orig_len = len(x)
x = x[-3:-1] + x + x[1:3]
y = y[-3:-1] + y + y[1:3]

t = np.arange(len(x))
ti = np.linspace(2, orig_len + 1, 10 * orig_len)

xi = interp1d(t, x, kind='cubic')(ti)
yi = interp1d(t, y, kind='cubic')(ti)

fig, ax = plt.subplots()
ax.plot(xi, yi)
ax.plot(x, y)
ax.margins(0.05)
plt.show()

enter image description here [/g2]

Обратите внимание, что вы получаете довольно «перерегулирование» с помощью этого метода. Это связано с кубической сплайновой интерполяцией. Предложение @ pythonstarter - еще один хороший способ справиться с этим, но кривые безье будут страдать от одной и той же проблемы (они в основном эквивалентны математически, это всего лишь вопрос о том, как определяются контрольные точки). Существует множество других способов обработки сглаживания, включая методы, которые предназначены для сглаживания многоугольника (например, полиномиальная аппроксимация с экспоненциальным ядром (PAEK)). Я никогда не пытался внедрить PAEK, поэтому я не уверен, как это связано. Если вам нужно сделать это более надежно, вы можете попробовать изучить PAEK или другой подобный метод.

0
задан fuglede 13 July 2018 в 16:01
поделиться

1 ответ

Если вам просто нужно сдвинуть индекс на единицу, вы можете сделать это напрямую, не касаясь pd.Series:

In [148]: df = pd.DataFrame([5, 10, 15, 12])

In [149]: df
Out[149]:
    0
0   5
1  10
2  15
3  12

In [150]: df.index += 1

In [151]: df
Out[151]:
    0
1   5
2  10
3  15
4  12
1
ответ дан fuglede 17 August 2018 в 12:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: