def grubbs(timeseries):
 series = scipy.array([x[1] for x in timeseries])
 stdDev = scipy.std(series)
 mean = np.mean(series)
 tail_average = tail_avg(timeseries)
 z_score = ((tail_average - mean) / stdDev)
 len_series = len(series)
 threshold = scipy.stats.t.isf((0.05 / (2 * len_series)), (len_series - 2))
 threshold_squared = (threshold * threshold)
 grubbs_score = (((len_series - 1) / np.sqrt(len_series)) * np.sqrt((threshold_squared / ((len_series - 2) + threshold_squared))))
 return (z_score > grubbs_score)

def grubbs ( timeseries ) : series = scipy . array ( [ x [ 1 ] for x in timeseries ] ) stdDev = scipy . std ( series ) mean = np . mean ( series ) tail_average = tail_avg ( timeseries ) z_score = ( ( tail_average - mean ) / stdDev ) len_series = len ( series ) threshold = scipy . stats . t . isf ( ( 0.05 / ( 2 * len_series ) ) , ( len_series - 2 ) ) threshold_squared = ( threshold * threshold ) grubbs_score = ( ( ( len_series - 1 ) / np . sqrt ( len_series ) ) * np . sqrt ( ( threshold_squared / ( ( len_series - 2 ) + threshold_squared ) ) ) ) return ( z_score > grubbs_score )
a timeseries is anomalous if the z score is greater than the grubbs score .