如何在Python中进行此聚合

时间:2015-03-11 03:09:20

标签: python json

我有一个JSON响应如下。

{
"2015-03-08": {
"www.ndtv.com": [
{
"traffic": 100,
"name": "Server1"
}
],
"www.profit.ndtv.com": [
{
"traffic": 49.69,
"name": "Server1"
},
{
"traffic": 50.31,
"name": "Server2"
}
]
},
"2015-03-03": {
"www.ndtv.com": [
{
"traffic": 100,
"name": "Server1"
}
],
"www.profit.ndtv.com": [
{
"traffic": 50.11,
"name": "Server1"
},
{
"traffic": 49.89,
"name": "Server2"
},
{
"traffic": 0,
"name": "Server3"
}
]
},
"2015-03-05": {
"www.ndtv.com": [
{
"traffic": 100,
"name": "Server1"
}
],
"www.profit.ndtv.com": [
{
"traffic": 50.36,
"name": "Server1"
},
{
"traffic": 49.64,
"name": "Server2"
}
]
},
"2015-03-04": {
"www.ndtv.com": [
{
"traffic": 100,
"name": "Server1"
}
],
"www.profit.ndtv.com": [
{
"traffic": 50.79,
"name": "Server1"
},
{
traffic: 49.21,
name: "Server2"
}
]
},
"2015-03-07": {
"www.ndtv.com": [
{
"traffic": 100,
"name": "Server1"
}
],
"www.profit.ndtv.com": [
{
"traffic": 51.48,
"name": "Server1"
},
{
"traffic": 48.52,
"name": "Server2"
}
]
},
2015-03-06: {
"www.ndtv.com": [ ],
"www.profit.ndtv.com": [
{
"traffic": 50.96,
"name": "Server1"
},
{
"traffic": 49.04,
"name": "Server2"
}
]
}
}

我需要在几天内汇总数据。例如,对于2015-03-08,我想为Server1添加所有流量,因此在我的示例中它将是(100+49.69)/2。我将它除以2,因为server1的#是2,并将其存储为父域。在这种情况下,输出将是。

{
2015-03-08: {
www.ndtv.com: [
{
traffic: 74.85,
name: "Server1"
},
{
traffic: 50.31,
name: "Server2"
}
]
}

我很困惑如何在Python中执行此操作。

1 个答案:

答案 0 :(得分:0)

补充:OP现在编辑了Q以显示正确的JSON,但暗示他实际处理的伪JSON是破坏的 - 用不带引号的密钥 - 他之前有过;所以我将离开A的开始,因为它可以帮助他处理实际上破坏的json。

首先,你需要一个黑客来修复你正在展示的那个严重破坏的JSON - 没有引用密钥!它们必须通过JSON标准(并且对于Python的json模块能够将JSON加载到Python数据结构中)。幸运的是,如果您展示的示例是规范性的,那么破损是非常系统的,并且可以修复。

假设x是您显示的字符串:

import re, json

z = re.sub(r'([^:\s]+):', r'"\1":', x)
y = json.loads(z)

现在在y中您拥有所需的数据结构。

所以现在您的任务更容易(取决于您的确切规格 - 例如,我将假设每天的子字典中的最短域是您想要聚合的域,服务器的顺序并不重要 - 这些都是猜测当然,你需要更准确地解释你的规格: - )。

通过这些猜测......:

import collections

res = {}
for d in y:
    dd = y[d]
    dom = min(dd, key=len)
    res[d] = {dom: []}
    serv_traf = collections.defaultdict(list)
    for subdom in dd:
        for ddd in dd[subdom]:
            serv_traf[ddd['name']].append(ddd['traffic'])
    for serv in serv_traf:
        traf = serv_traf[serv]
        restraf = sum(traf) / len(traf)
        res[d][dom].append({'name': serv, 'traffic': restraf})

应该做你想做的事。例如,对于您的示例已损坏x

import pprint
pprint.pprint(res)

所示:

{'2015-03-03': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 75.055},
                                 {'name': 'Server2', 'traffic': 49.89},
                                 {'name': 'Server3', 'traffic': 0}]},
 '2015-03-04': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 75.395},
                                 {'name': 'Server2', 'traffic': 49.21}]},
 '2015-03-05': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 75.18},
                                 {'name': 'Server2', 'traffic': 49.64}]},
 '2015-03-06': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 50.96},
                                 {'name': 'Server2', 'traffic': 49.04}]},
 '2015-03-07': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 75.74},
                                 {'name': 'Server2', 'traffic': 48.52}]},
 '2015-03-08': {'www.ndtv.com': [{'name': 'Server1', 'traffic': 74.845},
                                 {'name': 'Server2', 'traffic': 50.31}]}}

似乎至少与您的想法相近。

要将其重新设置为JSON,当然,您使用json.dumps(res) - 这不可避免地会为您提供正确 JSON ...希望您不需要破解它再次模仿你开始时破碎的那种?

相关问题