【问题标题】:How to carry out this aggregation in python如何在python中进行这种聚合
【发布时间】:2023-03-23 12:30:01
【问题描述】:

我有以下字典列表,其中包含 country 和相应服务器的值。

[
    {'country': 'KR', 'values': ['Server1']},
    {'country': 'IE', 'values': ['Server1', 'Server3', 'Server2']},
    {'country': 'IE', 'values': ['Server1', 'Server3']},
    {'country': 'DE', 'values': ['Server1']},
    {'country': 'DE', 'values': ['Server2']},
]

现在我需要计算特定国家/地区的每台服务器的百分比。例如,对于IE,两个列表的总和为5。因此,对于Server1,百分比将计算为(2/5)*100,因为IE 有两个Server1,其余的类似,然后将Server1 的百分比添加到字典中,percent 为钥匙。所以基本上对于上述结构,输出变成了。

[
    {"country": "KR", "percent": "100.0000", "values": ["Server1-100.0000"]},
    {"country": "IE", "percent": "40.000", "values": ["Server1-40.0", "Server3-40.0", "Server2-20.0"]},
    {"country" : "DE", "percent" : "50.0", "values" : ["Server1-50.0", "Server2-50.0"]},
]

我尝试了以下代码。

for i in range(len(response) - 1):
   for j in range((i+1), len(response) - 1):
     if response[i]['country'] == response[j]['country']:
       print response[i]['country'], response[j]['country']
       total = len(response[i]['values']) +  len(response[j]['values'])
       print total
       for item in response[i]['values']:
         for ktem in response[j]['values']:
           if item == ktem:
              if item == 'Server1':
                response[i]['percent'] =  200/total
              else:
                response[i][percent] = 0
              del response[j]

我坚持要进一步得到正确的百分比部分。有什么帮助吗?

【问题讨论】:

  • 百分比的值在每个国家/地区不是唯一的:例如,对于“IE”,server1 和 3 的百分比应该是 40,但 server2 的百分比应该是 20 ...
  • 是的,百分比字段仅填充了Server1 的百分比值。
  • 请直接告诉我们您想要的结果。
  • 我已经在问题中指定了输出。
  • 虽然需要一些时间,但我有一个很好的解决方案!

标签: python dictionary data-structures aggregation


【解决方案1】:

我有一个更紧凑的方法。

我认为它更具可读性和易于理解。可以参考如下:

这是你的 var 我不关心 response:

response = [
    {'country': 'KR', 'values': ['Server1']},
    {'country': 'IE', 'values': ['Server1', 'Server3', 'Server2']},
    {'country': 'IE', 'values': ['Server1', 'Server3']},
    {'country': 'DE', 'values': ['Server1']},
    {'country': 'DE', 'values': ['Server2']},
]

让我们合并这些值。

new_res = {}
for e in response:
    if e['country'] not in new_res:
        new_res[e['country']] = e['values']
    else:
        new_res[e['country']].extend(e['values'])

如果你想知道它的内容,你可以打印new_res。如下所示:

{
    'KR': ['Server1'],
    'DE': ['Server1', 'Server2'],
    'IE': ['Server1', 'Server3', 'Server2', 'Server1', 'Server3']
}

调用collections模块收集元素:

from collections import Counter
new_list = []
for country, values in new_res.items():
    # elements are stored as dictionary keys and their counts are stored as dictionary values
    merge_values = Counter(values)

    # calculate percentage
    new_values = []
    total = sum(merge_values.values())    
    for server_name, num in merge_values.items():
        #ex: Server1-40.0
        new_values.append("{0}-{1:.1f}".format(server_name, num*100/total))

    percent = merge_values["Server1"]*1.0*100/total

    new_list.append({"country": country,
                     "percent": percent,
                     "values": new_values})

计算完成后可以打印new_list

[{'country': 'KR', 'percent': 100.0, 'values': ['Server1-100.0']},
 {'country': 'DE', 'percent': 50.0,  'values': ['Server1-50.0', 'Server2-50.0']},
 {'country': 'IE', 'percent': 40.0,  'values': ['Server1-40.0', 'Server2-20.0', 'Server3-40.0']}]

所以你可以得到你想要的答案。

【讨论】:

  • 别忘了百分比字段(虽然问题的输出有点傻)
  • 那个 Counter 类非常方便。而不是 new_res 中的列表,您可以使用 Counter 代替
【解决方案2】:

假设你有

orig = [
    {'country': 'KR', 'values': ['Server1']},
    {'country': 'IE', 'values': ['Server1', 'Server3', 'Server2']},
    {'country': 'IE', 'values': ['Server1', 'Server3']},
    {'country': 'DE', 'values': ['Server1']},
    {'country': 'DE', 'values': ['Server2']},
]

您可以创建一个新字典,其中列出了哪些国家/地区的服务器及其数量

newDict = {}
for c in orig:
    if c['country'] not in newDict:
        newDict[c['country']] = dict()
    for s in c['values']:
        if s in newDict[c['country']]:
            newDict[c['country']][s] = newDict[c['country']][s] + 1
        else:
            newDict[c['country']][s] = 1

格式如下:

{'KR': {'Server1': 1}, 
 'DE': {'Server1': 1, 'Server2': 1}, 
 'IE': {'Server1': 2, 'Server2': 1, 'Server3': 2}}

然后您可以这样计算百分比:

output = []
for country in newList:
    total = 0
    for server in newList[country]:
        total = total + newList[country][server]    
    output.append({"country": country, "percent": (100.0 * newList[country]['Server1'])/total})

会产生

[{'country': 'KR', 'percent': 100.0}, 
 {'country': 'DE', 'percent': 50.0}, 
 {'country': 'IE', 'percent': 40.0}]

我将把它作为练习留给读者优化和添加您想要的其他字段

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2013-12-23
    • 1970-01-01
    • 2022-11-02
    • 2019-04-13
    • 2018-04-20
    • 1970-01-01
    • 2019-03-11
    相关资源
    最近更新 更多