【问题标题】:Matching key, value of two lists of dictionaries匹配两个字典列表的键、值
【发布时间】:2021-10-29 12:51:15
【问题描述】:

给定两个字典列表,例如 -

poo = [{
      "xmin":10,
      "ymin":100,
      "xmax":70,
      "ymax":120,
      "text":"fish",
}]

还有

foo = [{
      "class":"Animal",
      "percent":88.25,
      "box_points":[30, 90, 80, 110]
}]

产生如下输出:

poofoo = [{
    "class":"Animal",
    "text":"fish",
    "percent": 88.25,
    "box_points":{
          "xmin":10,
          "ymin":90,
          "xmax":80,
          "ymax":120}
]}

知道foo 字典列表中的box_points 也是xmin, ymin, xmax, ymax 格式。这些框点是系统检测到的边界框的坐标。

如何访问嵌套元素,比较它们然后合并元素?如果它们在空间上接近,则将它们合并,在此示例中,阈值为 10 个单位 (x,y)。

我已经试过了:

def boxOverlap(box1, box2):
    try:
        if(box1[0]<=box2[2] and box1[0]>=box2[0]) \
            or (box1[1]<=box2[3] and box1[1]>=box2[3]):
            return True
        else:
            return False
    except TypeError:
        print(f"{message_error}")

final_json = []

for el1, el2 in zip(foo, poo):        
    el1_box_format = [el1['x_min'], el1['y_min'], el1['x_max'], el1['y_max']]
    
    if(boxOverlap(el1_box_format, el2['box_points'])):
        final_json.append({"class":el2["name"],
                           "text":el1["text"],
                           "confidence":el2["percentage_probability"],
                           "boxpoints":None
                          })

请注意,我创建了一个函数,用于在框是否重叠时返回布尔值(稍后我将实现阈值)。但问题是,我只想比较空间上接近的字典,而现在,由于我使用的是zip(foo, poo),它只能在成对元素中运行。

【问题讨论】:

  • 请澄清你的输出,为什么动物在里面?
  • 我在这里拼错了,它是“class”而不是“name”。谢谢你带来这个。
  • 也不清楚 box_points 如何与 xmin 等相关
  • 已在帖子中更正!

标签: python list dictionary


【解决方案1】:

一个简单的解决方案如下所示。

poo = [{
    "xmin": 10,
    "ymin": 100,
    "xmax": 70,
    "ymax": 120,
    "text": "fish",
}]

foo = [{
    "class": "Animal",
    "percent": 88.25,
    "box_points": [30, 90, 80, 110]
}]


def merge(p: dict, f: dict):
    coords = list(p.values())[:-1]
    box_coords = f.get("box_points")
    box_points = {"xmin": min(coords[0], box_coords[0]),
                  "ymin": min(coords[1], box_coords[1]),
                  "xmax": max(coords[2], box_coords[2]),
                  "ymax": max(coords[3], box_coords[3]),

                  }
    f['box_points'] = box_points
    f['text'] = p.get('text')
    return f


poofoo = [merge(poo[index], foo[index]) for index in range(len(poo))]

输出:

[
    {
        "class": "Animal",
        "percent": 88.25,
        "box_points": {
            "xmin": 10,
            "ymin": 90,
            "xmax": 80,
            "ymax": 120
        },
        "text": "fish"
    }
]

这假设两个列表的长度相同,坐标顺序也一直相同。

【讨论】:

  • 谢谢!我不知道get方法。但是考虑到列表的大小不同,我怎么能扩展你的代码呢?
【解决方案2】:

这不是一个真正通用的解决方案,因为我不清楚这一点。

poo = [{
      "xmin":10,
      "ymin":100,
      "xmax":70,
      "ymax":120,
      "text":"fish",
}]

foo = [{
      "class":"Animal",
      "percent":88.25,
      "box_points":[30, 90, 80, 110]
}]

foo[0]["xmin"] = foo[0]["box_points"][0]
foo[0]["ymin"] = foo[0]["box_points"][1]
foo[0]["xmax"] = foo[0]["box_points"][2]
foo[0]["ymax"] = foo[0]["box_points"][3]
foo[0].pop("box_points")


poofoo = [{}]

for kp in poo[0]:
    for kf in foo[0]:
       if kp == kf:
           if kp not in poofoo[0]:
               if abs(poo[0][kp] - foo[0][kf]) < 10:
                   poofoo[0][kp] = poo[0][kp] #change if the smallest value for the mins is needed and the biggest value for maxs
       else:
           if kp not in poofoo:
               poofoo[0][kp] = poo[0][kp]
           if kf not in poofoo:
               poofoo[0][kf] = foo[0][kf]
    

【讨论】:

    猜你喜欢
    • 2021-01-10
    • 2017-05-01
    • 2021-11-17
    • 2020-10-21
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多