How about something like this:
def aggregate(stats):
aggregated = {}
for stat in stats:
key = stat.pop(0)
stat = map(float, stat)
if key not in aggregated:
vals = {"avg": []}
aggregated[key] = vals
aggregated[key]['min'] = min(stat[0], aggregated[key].setdefault('min', stat[0]))
aggregated[key]['max'] = max(stat[1], aggregated[key].setdefault('max', stat[1]))
aggregated[key]['avg'].append(stat[2])
return aggregated
def print_stats(aggregated):
for k, v in aggregated.items():
print k,
for k1, v1 in v.items():
if k1 == 'avg':
print "%s: %s" % (k1, sum(v1) / len(v1)),
else:
print "%s: %s" % (k1, v1),
print
stats = [
['findProductByPartNumber', '336.0', '336.0', '336.0'],
['findProductByPartNumber', '336.0', '339.0', '337.5'],
['findProductByPartNumber', '336.0', '339.0', '338.0'],
['findProductByPartNumber', '336.0', '341.0', '338.75'],
['findProductByPartNumber', '336.0', '353.0', '341.6'],
['findProductById', '841.0', '841.0', '841.0'],
['findProductByPartNumber', '336.0', '920.0', '438.0'],
['findProductByPartNumber', '336.0', '944.0', '510.29'],
['findProductByPartNumber', '336.0', '952.0', '565.5'],
['findProductByPartNumber', '336.0', '975.0', '611.0'],
['findProductsByCategory', '113.0', '113.0', '113.0'],
['findProductById', '161.0', '841.0', '501.0'],
['findProductByPartNumber', '255.0', '975.0', '575.4']
]
print_stats(aggregate(stats))
OUTPUT
findProductsByCategory max: 113.0 avg: 113.0 min: 113.0
findProductById max: 841.0 avg: 671.0 min: 161.0
findProductByPartNumber max: 975.0 avg: 439.204 min: 255.0
As far as 90th percentile, it isn't possible to calculate without the individual samples unless you just use .9 * avg.