2016-11-23 1 views
0

У меня есть ряд чисел:метод, чтобы определить точку, где числа отпасть резко

numbers = [100, 101, 99, 102, 99, 98, 100, 97.5, 98, 99, 95, 93, 90, 85, 80] 

plot of numbers

Это очень, чтобы увидеть невооруженным глазом, что цифры начинают резко падать примерно около 10, но есть ли простой способ идентифицировать эту точку (или близко к ней) по оси x?

Это делается ретроспективно, поэтому вы можете использовать весь список чисел, чтобы выбрать точку оси x, где ускоряется выпадение.

Решения Python предпочтительны, но псевдокод или общая методология тоже прекрасны.

+0

Возможно, точка, где разница от одного числа к другому больше половины стандартного отклонения? –

+0

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

+0

Совокупные оценки Z, вероятно, сработают. – Chris

ответ

0

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

Это работает только с уменьшением, так как я проверяю только на cdf < 0.05, но он работает очень хорошо.

import numpy as np 
from scipy import stats 
import matplotlib.pyplot as plt 

numbers = np.array([100, 101, 99, 102, 99, 98, 100, 97.5, 98, 99, 95, 93, 90, 85, 80]) 

# Calculate a running mean 
cum_mean = numbers.cumsum()/(np.arange(len(numbers)) + 1) 

# Calculate a running standard deviation 
cum_std = np.array([numbers[:i].std() for i in range(len(numbers))]) 

# Calculate a z value 
cum_z = (numbers[1:] - cum_mean[:-1])/cum_std[:-1] 

# Add in NA vals to account for records without sample size 
z_vals = np.concatenate((np.zeros(1+2), cum_z[2:]), axis=0) 

# Calculate cdf 
cum_t = np.array([stats.t.cdf(z, i) for i, z in enumerate(z_vals)]) 

# Identify first number to fall below threshold 
first_deviation = np.where(cum_t < 0.05)[0].min() 

fig, ax = plt.subplots() 

# plot the numbers and the point immediately prior to the decrease 
ax.plot(numbers) 
ax.axvline(first_deviation-1, color='red') 

numbers with drop detected

Смежные вопросы