Есть ли способ pythoni c для расширения линии в графе из двух точек данных? - PullRequest
0 голосов
/ 23 февраля 2020

Я создал набор данных случайного блуждания, вычислил локальные минимальные и максимальные точки и нанес их на график с помощью matplotlib. Мне интересно, есть ли способ в Python использовать точки данных, чтобы создать линию и расширить эту линию для каждого периода в том же «направлении», что и предыдущие две точки. Смотрите картинку ниже. Есть идеи, как мне это сделать?

Спасибо за любую помощь!

enter image description here

import random
from scipy.signal import argrelextrema

#create random walk
random.seed(1)
random_walk = list()
random_walk.append(-1 if random.random() < 0.5 else 1)
for i in range(1, 20):
    movement = -1 if random.random() < 0.5 else 1
    value = random_walk[i-1] + movement
    random_walk.append(value)


df  = pd.DataFrame(random_walk, columns=["data"])

n=3
# Find local peaks
df['min'] = df.iloc[argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']


plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')


plt.plot(df.index, df['data'])
plt.plot(df['min'], '.r-') 
plt.plot(df['max'], 'xb-')

plt.show()


print(df['min'])
print(df['min'])

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Звучит так, как будто вы хотите линейно проецировать, используя два (я буду использовать первый и последний) локальные минимумы и максимумы. Таким образом, вы должны определить эти точки, а затем подобрать функцию для линейного прохождения через них и построить эту функцию с набором точек, выходящих за пределы ваших данных:

from random import random
import pandas as pd
from scipy import signal
import numpy as np
import matplotlib.pyplot as plt

#create random walk
random.seed(1)
random_walk = list()
random_walk.append(-1 if random() < 0.5 else 1)
for i in range(1, 20):
    movement = -1 if random() < 0.5 else 1
    value = random_walk[i-1] + movement
    random_walk.append(value)


df  = pd.DataFrame(random_walk, columns=["data"])

n=3
# Find local peaks
df['min'] = df.iloc[signal.argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[signal.argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']

min_points = [t for t in tuple(zip(df.index, df['min'])) if t[1] == t[1]] # zips and removes NaNs
max_points = [t for t in tuple(zip(df.index, df['max'])) if t[1] == t[1]] # zips and removes NaNs
min_end_points = (min_points[0], min_points[-1])
max_end_points = (max_points[0], max_points[-1])

plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')

min_fit = np.poly1d(np.polyfit([x[0] for x in min_end_points], [x[1] for x in min_end_points], 1))
max_fit = np.poly1d(np.polyfit([x[0] for x in max_end_points], [x[1] for x in max_end_points], 1))

x_proj = np.linspace(0, 30, 30)
plt.plot(df.index, df['data'])
plt.plot(x_proj, min_fit(x_proj), '-r') 
plt.plot(x_proj, max_fit(x_proj), '-b')

plt.show()

Результат:

plot

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

0 голосов
/ 23 февраля 2020

Если я вас правильно понял, то сработает:

import random
from scipy.signal import argrelextrema

#create random walk
random.seed(1)
random_walk = list()
random_walk.append(-1 if random.random() < 0.5 else 1)
for i in range(1, 20):
    movement = -1 if random.random() < 0.5 else 1
    value = random_walk[i-1] + movement
    random_walk.append(value)


df  = pd.DataFrame(random_walk, columns=["data"])

n=3
# Find local peaks
df['min'] = df.iloc[argrelextrema(df.data.values, np.less_equal, order=n)[0]]['data']
df['max'] = df.iloc[argrelextrema(df.data.values, np.greater_equal, order=n)[0]]['data']

mins = [(k, v) for k, v in list(df[['min']].dropna().to_dict().values())[0].items()]
maxs = [(k, v) for k, v in list(df[['max']].dropna().to_dict().values())[0].items()]
plt.scatter(df.index, df['min'], c='r')
plt.scatter(df.index, df['max'], c='g')
for previous, current in zip(mins, mins[1:]):
    xs = [a for a,b in [previous, current]]
    ys = [b for a,b in [previous, current]]
    plt.plot(xs, ys)

for previous, current in zip(maxs, maxs[1:]):
    xs = [a for a,b in [previous, current]]
    ys = [b for a,b in [previous, current]]
    plt.plot(xs, ys)

plt.plot(df.index, df['data'])
plt.plot(df['min'], '.r-') 
plt.plot(df['max'], 'xb-')

plt.show()

Результат:

enter image description here

...