将数据框中的JSON列转换为简单的值数组

时间:2018-11-12 02:07:42

标签: python json pandas jupyter-notebook

我正在尝试将bbox(边界框)列中的JSON转换为Jupyter笔记本中python中DL项目的简单值数组。

可能的标签为以下类别:[玻璃,纸板,垃圾桶,金属,纸张]。

[{"left":191,"top":70,"width":183,"height":311,"label":"glass"}]

TO

([191 70 183 311], 0)

我正在寻找帮助,以将JSON对象中的bbox列转换为包含所有图像名称和相关bbox的单个CSV。

FN and BBOX

更新

当前列是一个系列,因此,每次尝试在该列上应用JSON操作时,我都会不断收到“ TypeError:JSON对象必须为str,字节或字节数组,而不是'Series'”。到目前为止,我已经尝试将列转换为JSON对象,然后从键中提取值。

BB_CSV enter image description here

enter image description here

2 个答案:

答案 0 :(得分:1)

您将要使用JSON解码器:https://docs.python.org/3/library/json.html

import json
li = json.loads('''[{"left":191,"top":70,"width":183,"height":311,"label":"glass"}]''')
d = dictionary = li[0]
result = ([d[key] for key in "left top width height".split()], 0)
print(result)

编辑:

如果要将映射从字典中提取值的操作映射到列表的所有元素,则可以执行以下操作:

extracted = []
for element in li:
    result = ([element[key] for key in "left top width height".split()], 0)
    extracted.append(result)

# print(extracted)
print(extracted[:10])
# `[:10]` is there to limit the number of item displayed to 10

类似地,根据我的评论,如果您不希望列表中提取的数字之间使用逗号,则可以使用:

without_comma = []
for element, zero in extracted:
    result_string = "([{}], 0)".format(" ".join([str(value) for value in element]))
    without_comma.append(result_string)

答案 1 :(得分:0)

看起来bbox列的每一行在dictionary的内部都包含一个list。我尝试按照以下方式复制您的问题。 编辑:澄清以下解决方案是假设您所指的“ JSON对象”表示为包含单个字典的list,这似乎是每个字典的含义。您的示例和屏幕截图。

# Create empty sample DataFrame with one row
df = pd.DataFrame([None],columns=['bbox'])

# Assign your sample item to the first row
df['bbox'][0] = [{"left":191,"top":70,"width":183,"height":311,"label":"glass"}]

现在,要简单地解压行,您可以执行以下操作:

df['bbox_unpacked'] = df['bbox'].map(lambda x: x[0].values())

这将为您带来一个包含5个项目的tuple的新列。

如果想进一步应用标签,您可能需要创建一个包含标签逻辑的字典。根据您在注释中给出的示例,我已经完成:

labels = {
    'cardboard': 1,
    'trash': 2,
    'glass': 3
}

如果您想要一个单行解决方案而不编写自己的函数,这应该可以得到您想要的布局。

df['bbox_unpacked'] = df['bbox'].map(lambda x: (list(x[0].values())[:4],labels.get(list(x[0].values())[-1])))

一种更具可读性的解决方案是使用.apply()方法定义您自己的函数。 编辑:由于看起来您的JSON对象被存储为str行中的DataFrame,因此,我首先添加了json.loads(row)来处理字符串,然后再检索键。您需要import json才能运行。

import json    

def unpack_bbox(row, labels):

    # load the string into a JSON object (in this
    # case a list of length one containing the dictionary;
    # index the list to its first item [0] and use the .values()
    # dictionary method to access the values only 

    keys = list(json.loads(row)[0].values())

    bbox_values = keys[:4]
    bbox_label = keys[-1]

    label_value = labels.get(bbox_label)

    return bbox_values, label_value

df['bbox_unpacked'] = df['bbox'].apply(unpack_bbox,args=(labels,))