【问题标题】:Counting multiple json inputs python计算多个json输入python
【发布时间】:2021-09-16 23:11:34
【问题描述】:

我收到这样的输入:

input 1:

{

"name": "Ben",
"description": "Ben",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
}

input 2

{

"name": "Ice",
"description": "Ice",
"attributes": [
    {
    "type": "Background",
    "value": "Green"
    },
    {
    "type": "Hair-color",
    "value": "White"
    }
]
}

input 3

{

"name": "Itay",
"description": "Itay",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
}

我要做的是计算每种背景和每种发色出现的数量。 (这些是示例示例,实际上有更多类型和不同的值)

假设在这些示例中,我们有 2 个默认背景为背景的对象,那么我想要这样计数:

Backround default count=2
hair-color brown = 2
background green = 1
hair-color white = 1

我想要最有效的代码,因为代码还有其他方面,此外它会在数千个查询上运行,而不仅仅是两个,所以也需要在好的时候运行 :D 到目前为止我的代码:

import requests
import json
from collections import Counter
from collections import defaultdict
from time import sleep


attributes = []
test_dict = defaultdict(list)

for i in range(min_id, max_id+1):
    api = 'api/v1/test/{}'.format(i)
    response = requests.get(api)

    item_dict = json.loads(response.text)

    for item in item_dict['attributes']:
        attributes.append(item["trait_type"]) if item["trait_type"] not in attributes else attributes
        test_dict[item["trait_type"]].append(item["value"])
    sleep(0.02)

for attribute in attributes:
    print(attribute)
    print(Counter(test_dict[attribute]))

【问题讨论】:

  • 当你尝试这样做时发生了什么?你走了多远?出了什么问题?
  • 我知道如何计算背景、头发颜色、默认值、棕色、绿色和白色出现的次数。我不知道/不知道如何将背景与默认和绿色以及头发颜色与棕色和白色相关联。
  • 分享你的工作代码
  • @Sabil 我没有太多工作代码,主要是与 API 交互的基础。我想做的是创建一个像这样的字典:{backround: default, count: 2} 但这可能会使进一步的编码复杂化。最后,我想计算总对象的数量(在我们的例子中为 3),然后将每个值除以总数,看看它占总数的百分比。
  • 我只是更新了我的答案,希望它能解决您的所有问题,包括比率计算。 :)

标签: python json formatting


【解决方案1】:

这应该适合你:

def constract_data(data_dict):
    output = []
    total_count = 0

    for data in data_dict:
        attributes = data["attributes"]
        for attribute in attributes:
            total_count += 1
            dict_key = attribute["type"].lower()
            dict_value = attribute["value"].lower()
            dict_index = [index for index, data in enumerate(output) if data.get(dict_key, "") == dict_value]

            if dict_index:
                output[dict_index[0]]['count'] += 1
            else:
                atb_dict = {dict_key: dict_value, 'count': 1}
                output.append(atb_dict)

    return output, total_count

def calculate_occurrence_ratio(data_dict, total_count):
    for index, data in enumerate(data_dict):
        count = data.get('count', 0)
        ratio = round(((count / total_count) * 100), 2)
        data['ratio'] = f'{ratio}%'

    return data_dict

data_dict = [
   {
      "name":"Ice",
      "description":"Ice",
      "attributes":[
         {
            "type":"Background",
            "value":"Green"
         },
         {
            "type":"Hair-color",
            "value":"White"
         }
      ]
   },
   {
      "name":"Ben",
      "description":"Ben",
      "attributes":[
         {
            "type":"Background",
            "value":"Default"
         },
         {
            "type":"Hair-color",
            "value":"Brown"
         }
      ]
   },
   {
      "name":"Itay",
      "description":"Itay",
      "attributes":[
         {
            "type":"Background",
            "value":"Default"
         },
         {
            "type":"Hair-color",
            "value":"Brown"
         }
      ]
   }
]

output_data, total_count = constract_data(data_dict)

output_data = calculate_occurrence_ratio(output_data, total_count)

print(output_data)

输出:

[{'background': 'green', 'count': 1, 'ratio': '16.67%'}, {'hair-color': 'white', 'count': 1, 'ratio': '16.67%'}, {'background': 'default', 'count': 2, 'ratio': '33.33%'}, {'hair-color': 'brown', 'count': 2, 'ratio': '33.33%'}]

【讨论】:

  • 您认为更容易使用的输出是什么?你的或这个:{'background': {'green': 1, 'default': 2}, 'hair-color': {'white': 1, 'brown': 2}}
  • 这取决于你想要的输出是什么?
  • 总的来说,我想做的是给每个特征打分。然后,如果用户具有某种特征,则给它打分。所以基本上我想通过分数来计算每个用户的稀有度。假设 hair_color 为白色的分数是 100,Ice 将获得 100 分。
  • 哦,那我必须根据您的要求更新我的答案。 :)
  • 好吧,太棒了,对所有的喧嚣感到抱歉:D 你的回答太棒了,并且完美地计算了一切。非常喜欢:D
【解决方案2】:

此解决方案适合您:

list_data = [
{
"name": "Ice",
"description": "Ice",
"attributes": [
    {
    "type": "Background",
    "value": "Green"
    },
    {
    "type": "Hair-color",
    "value": "White"
    },
    {
    "type": "other",
    "value": "White"
    }
]
},
{

"name": "Ben",
"description": "Ben",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
},{

"name": "Itay",
"description": "Itay",
"attributes": [
    {
    "type": "Background",
    "value": "Default"
    },
    {
    "type": "Hair-color",
    "value": "Brown"
    }
]
},
]
output = {}
all_count = {}
for user in list_data:
    data = user["attributes"]
    for dat in data:
        typeu = dat["type"]
        if typeu not in all_count:
            all_count[typeu]=1
        else:
            all_count[typeu]+=1

for user in list_data:
    data = user["attributes"]
    for dat in data:
        typeu = dat["type"]
        if typeu not in output:
            output[typeu]={}
        if dat["value"] not in output[typeu]:
            output[typeu][dat["value"]] = "1 with: {}%".format(int(1/all_count[typeu]*100))
        else:
            count = int(output[typeu][dat["value"]][0])+1
            output[typeu][dat["value"]] = str(count)+" with: {}%".format(int(count/all_count[typeu]*100))
print(output)

【讨论】:

  • 就像我在帖子中所说的那样,有时属性不仅仅是背景和头发颜色。脚本需要自己识别它们...
  • 好的,我编辑了它
  • 你认为有没有办法计算它发生的机会?所以基本上只需将每个项目的数量除以总用户数:Backround default:2 66% of it occuring
  • 我已经编辑过了。你能把它标记为解决方案吗?
  • 当我把它放在我的代码中时,一些属性显示为 100% 有些不是,总百分比不是 100% 示例:{'background': {'crisp green': '1 Ratio: 100%', 'dashing purple': '2 Ratio: 66%', 'spiffy blue': '1 Ratio: 25%', 'dapper cyan': '2 Ratio: 33%'}
【解决方案3】:

这是另一种方法:

from collections import defaultdict
data_dict = [
   {
      "name":"Ice",
      "description":"Ice",
      "attributes":[
         {
            "type":"Background",
            "value":"Green"
         },
         {
            "type":"Hair-color",
            "value":"White"
         }
      ]
   },
   {
      "name":"Ben",
      "description":"Ben",
      "attributes":[
         {
            "type":"Background",
            "value":"Default"
         },
         {
            "type":"Hair-color",
            "value":"Brown"
         }
      ]
   },
   {
      "name":"Itay",
      "description":"Itay",
      "attributes":[
         {
            "type":"Background",
            "value":"Default"
         },
         {
            "type":"Hair-color",
            "value":"Brown"
         }
      ]
   }
]

out = defaultdict(lambda: defaultdict(int))
tot_count = defaultdict(int)
for data in data_dict:
    for attri in data['attributes']:
        tot_count[attri['type']]+=1
        out[attri['type']][attri['value']]+=1
for k, v in out.items():
    for k1, v1 in v.items():
        print (f'{k.lower()} {k1} count={v1} ratio={int(v1*100/tot_count[k])}%')

输出:

background Green count=1 ratio=33%
background Default count=2 ratio=66%
hair-color White count=1 ratio=33%
hair-color Brown count=2 ratio=66%

【讨论】:

    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多