def asPercent(seriesList1, seriesList2orNumber): assert len( seriesList1 ) == 1, "asPercent series arguments must reference *exactly* 1 series" series1 = seriesList1[0] if type(seriesList2orNumber) is list: assert len( seriesList2orNumber ) == 1, "asPercent series arguments must reference *exactly* 1 series" series2 = seriesList2orNumber[0] name = "asPercent(%s,%s)" % (series1.name, series2.name) series = (series1, series2) step = reduce(lcm, [s.step for s in series]) for s in series: s.consolidate(step / s.step) start = min([s.start for s in series]) end = max([s.end for s in series]) end -= (end - start) % step values = (safeMul(safeDiv(v1, v2), 100.0) for v1, v2 in izip(*series)) else: number = float(seriesList2orNumber) name = "asPercent(%s,%.1f)" % (series1.name, number) step = series1.step start = series1.start end = series1.end values = (safeMul(safeDiv(v, number), 100.0) for v in series1) series = TimeSeries(name, start, end, step, values) series.pathExpression = name return [series]
def stdev(seriesList, time): count = 0 for series in seriesList: stddevs = TimeSeries("stddev(%s,%.1f)" % (series.name, float(time)), series.start, series.end, series.step, []) stddevs.pathExpression = "stddev(%s,%.1f)" % (series.name, float(time)) avg = safeDiv(safeSum(series[:time]), time) sumOfSquares = sum(map(lambda (x): x * x, series[:time])) (sd, sumOfSquares) = doStdDev(sumOfSquares, 0, 0, time, avg) stddevs.append(sd) for (index, el) in enumerate(series[time:]): if el is None: continue toDrop = series[index] if toDrop is None: toDrop = 0 s = safeSum([safeMul(time, avg), el, -toDrop]) avg = safeDiv(s, time) (sd, sumOfSquares) = doStdDev(sumOfSquares, toDrop, series[index + time], time, avg) stddevs.append(sd) for i in range(0, time - 1): stddevs.insert(0, None) seriesList[count] = stddevs count = count + 1 return seriesList
def nonNegativeDerivative( seriesList, maxValue=None ): # useful for watching counter metrics that occasionally wrap results = [] for series in seriesList: newValues = [] prev = None for val in series: if None in (prev, val): newValues.append(None) prev = val continue diff = val - prev if diff >= 0: newValues.append(diff) elif maxValue is not None and maxValue >= val: newValues.append(prev + (maxValue - val)) else: newValues.append(None) prev = val newName = "nonNegativeDerivative(%s)" % series.name newSeries = TimeSeries(newName, series.start, series.end, series.step, newValues) newSeries.pathExpression = newName results.append(newSeries) return results
def diffSeries(*seriesLists): (seriesList, start, end, step) = normalize(seriesLists) name = "diffSeries(%s)" % ','.join( set([s.pathExpression for s in seriesList])) values = (safeDiff(row) for row in izip(*seriesList)) series = TimeSeries(name, start, end, step, values) series.pathExpression = name return [series]
def averageSeries(*seriesLists): (seriesList, start, end, step) = normalize(seriesLists) #name = "averageSeries(%s)" % ','.join((s.name for s in seriesList)) name = "averageSeries(%s)" % ','.join( set([s.pathExpression for s in seriesList])) values = (safeDiv(safeSum(row), safeLen(row)) for row in izip(*seriesList)) series = TimeSeries(name, start, end, step, values) series.pathExpression = name return [series]
def sumSeries(*seriesLists): try: (seriesList, start, end, step) = normalize(seriesLists) except: return [] #name = "sumSeries(%s)" % ','.join((s.name for s in seriesList)) name = "sumSeries(%s)" % ','.join( set([s.pathExpression for s in seriesList])) values = (safeSum(row) for row in izip(*seriesList)) series = TimeSeries(name, start, end, step, values) series.pathExpression = name return [series]
def log(seriesList, base=10): results = [] for series in seriesList: newValues = [] for val in series: if val is None: newValues.append(None) else: newValues.append(math.log(val, base)) newName = "log(%s, %s)" % (series.name, base) newSeries = TimeSeries(newName, series.start, series.end, series.step, newValues) newSeries.pathExpression = newName results.append(newSeries) return results
def integral(seriesList): results = [] for series in seriesList: newValues = [] current = 0.0 for val in series: if val is None: newValues.append(None) else: current += val newValues.append(current) newName = "integral(%s)" % series.name newSeries = TimeSeries(newName, series.start, series.end, series.step, newValues) newSeries.pathExpression = newName results.append(newSeries) return results
def derivative(seriesList): results = [] for series in seriesList: newValues = [] prev = None for val in series: if None in (prev, val): newValues.append(None) prev = val continue newValues.append(val - prev) prev = val newName = "derivative(%s)" % series.name newSeries = TimeSeries(newName, series.start, series.end, series.step, newValues) newSeries.pathExpression = newName results.append(newSeries) return results
def movingAverage(seriesList, time): count = 0 for series in seriesList: movAvg = TimeSeries( "movingAverage(%s,%.1f)" % (series.name, float(time)), series.start, series.end, series.step, []) movAvg.pathExpression = "movingAverage(%s,%.1f)" % (series.name, float(time)) avg = safeDiv(safeSum(series[:time]), time) movAvg.append(avg) for (index, el) in enumerate(series[time:]): if el is None: continue toDrop = series[index] if toDrop is None: toDrop = 0 s = safeSum([safeMul(time, avg), el, -toDrop]) avg = safeDiv(s, time) movAvg.append(avg) for i in range(0, time - 1): movAvg.insert(0, None) seriesList[count] = movAvg count = count + 1 return seriesList