Python:从API列表计算度量

Python:从API列表计算度量,python,arrays,statistics,metrics,Python,Arrays,Statistics,Metrics,我有一组数据,如下所示: #API name, min, max, average ['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

我有一组数据,如下所示:

#API name, min, max, average
['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']
API, Min, Max, Average, 90th Percentile
findProductByPartNumber, 278.69, 770.25, 458.69, 565.5
findProductById, 373.0, 841.0, 571.67, 501.0
findProductsByCategory, 112.33, 187.17, 154.46, 167.75
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))
我想做的是,对于每个单独的API,生成如下内容:

#API name, min, max, average
['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']
API, Min, Max, Average, 90th Percentile
findProductByPartNumber, 278.69, 770.25, 458.69, 565.5
findProductById, 373.0, 841.0, 571.67, 501.0
findProductsByCategory, 112.33, 187.17, 154.46, 167.75
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))
这是上面每个API的聚合结果。在Python中实现这一点的最佳方法是什么

编辑:

我有下面的Java代码,这是我想要的。Java是我最好的语言,我正在努力学习Python,但我不熟悉数据结构

double[] apiValues = new double[3];
apiValues[0] = Double.valueOf(min);
apiValues[1] = Double.valueOf(max);
apiValues[2] = Double.valueOf(average);
parseAPILogs.registerAPI(name, apiValues);
...
...
private static void registerAPI(String apiName, double[] apiValues) {
    if(!averagePerAPI.containsKey(apiName)) {
        APIData data = new APIData();
        data.addValues(apiValues);
        averagePerAPI.put(apiName, data);
    } else {
        averagePerAPI.get(apiName).addValues(apiValues);
}
}

APIData Java类在这里已经有点过时了,但是你可以看到我的想法。

类似这样的东西怎么样:

#API name, min, max, average
['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']
API, Min, Max, Average, 90th Percentile
findProductByPartNumber, 278.69, 770.25, 458.69, 565.5
findProductById, 373.0, 841.0, 571.67, 501.0
findProductsByCategory, 112.33, 187.17, 154.46, 167.75
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))
输出

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

至于第90百分位,如果不使用单个样本,则无法进行计算,除非您仅使用.9*平均值。

这样的值怎么样:

#API name, min, max, average
['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']
API, Min, Max, Average, 90th Percentile
findProductByPartNumber, 278.69, 770.25, 458.69, 565.5
findProductById, 373.0, 841.0, 571.67, 501.0
findProductsByCategory, 112.33, 187.17, 154.46, 167.75
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))
arr = [ ['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']]

d = list(set([item[0] for item in arr]))
d = dict(zip(d, [[0, 0, 0, 0] for k in range(len(d))]))

for k in arr:
    d[k[0]][0] = min(k[1], d[k[0]][0]) if k[1] is 0 else k[1]
    d[k[0]][1] = max(k[2], d[k[0]][1])
    d[k[0]][2] = sum(map(lambda x: float(x[3]) if x[0] is k[0] else 0, [api for api in arr])) / len(filter(lambda x: x is k[0], [api[0] for api in arr]))

for k in d.keys():
    print "{0} {1} {2} {3} {4}".format(k, d[k][0], d[k][1], d[k][2], d[k][3])
输出

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

至于第90个百分位,如果没有单个样本,就无法计算,除非您仅使用.9*平均值。

您尝试过什么吗?我回答,但是您应该提供您在将来尝试过的代码,以显示您的努力。我已经编辑了一些Java代码,其中包含了实现这一点的Java代码,但我正在尝试学习Python,并且我提出的任何东西都没有真正起到作用。我对Python数据结构不太熟悉,所以希望可以开始一些示例代码。您尝试过什么吗?我回答,但是您应该提供您在将来尝试过的代码,以显示您的努力。我已经编辑了一些Java代码,其中包含了实现这一点的Java代码,但我正在尝试学习Python,并且我提出的任何东西都没有真正起到作用。我对Python数据结构不太熟悉,所以希望能够开始一些示例代码。谢谢您的回复。如上所述,我已经将统计数据硬编码到多维数组中,但在尝试执行时出现了此错误。有什么想法吗?回溯(最近一次调用):文件“/parselogs.py”,第109行,在aggregateStats=aggregate(stats)文件中“/parselogs.py”,第23行,在aggregate aggregated[key]['min']=min(stat[0],aggregated[key].setdefault('min',stat[0])中TypeError:“str”对象不可调用您可能通过执行类似于
min=
的操作来覆盖内置的
min
函数。当您这样做时,您正在替换对内置函数的引用,这是不允许的。谢谢-就是这样。这里的两个解决方案都很有效,但我会接受你的,因为这是第一个。非常感谢你的帮助。谢谢你的回复。如上所述,我已经将统计数据硬编码到多维数组中,但在尝试执行时出现了此错误。有什么想法吗?回溯(最近一次调用):文件“/parselogs.py”,第109行,在aggregateStats=aggregate(stats)文件中“/parselogs.py”,第23行,在aggregate aggregated[key]['min']=min(stat[0],aggregated[key].setdefault('min',stat[0])中TypeError:“str”对象不可调用您可能通过执行类似于
min=
的操作来覆盖内置的
min
函数。当您这样做时,您正在替换对内置函数的引用,这是不允许的。谢谢-就是这样。这里的两个解决方案都很有效,但我会接受你的,因为这是第一个。非常感谢您的帮助。谢谢您的回答,但我得到了一个与其他解决方案类似的错误。有什么想法吗?回溯(最近一次调用):文件“/parselogs.py”,第103行,在d[k[0][1]=max(k[2],d[k[0]][1])TypeError中:“str”对象不可调用谢谢您的回答,但我得到的错误与其他解决方案类似。有什么想法吗?回溯(最近一次调用):文件“/parselogs.py”,第103行,在d[k[0][1]=max(k[2],d[k[0]][1])类型错误:“str”对象不可调用
arr = [ ['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']]

d = list(set([item[0] for item in arr]))
d = dict(zip(d, [[0, 0, 0, 0] for k in range(len(d))]))

for k in arr:
    d[k[0]][0] = min(k[1], d[k[0]][0]) if k[1] is 0 else k[1]
    d[k[0]][1] = max(k[2], d[k[0]][1])
    d[k[0]][2] = sum(map(lambda x: float(x[3]) if x[0] is k[0] else 0, [api for api in arr])) / len(filter(lambda x: x is k[0], [api[0] for api in arr]))

for k in d.keys():
    print "{0} {1} {2} {3} {4}".format(k, d[k][0], d[k][1], d[k][2], d[k][3])