4维嵌套字典到pandas数据框

时间:2016-09-22 08:49:15

标签: python json pandas dictionary dataframe

我需要你帮助将多维dict转换为pandas数据框。我从一个JSON文件中获取dict,我从API调用(Shopify)中检索。

response = requests.get("URL", auth=("ID","KEY")) 
data = json.loads(response.text)

“数据”字典如下所示:

 {'orders': [{'created_at': '2016-09-20T22:04:49+02:00',
             'email': 'test@aol.com',
             'id': 4314127108,
             'line_items': [{'destination_location': 
                                       {'address1': 'Teststreet 12',
                                        'address2': '',
                                        'city': 'Berlin',
                                        'country_code': 'DE',
                                        'id': 2383331012,
                                        'name': 'Test Test',
                                        'zip': '10117'}, 
                             'gift_card': False,
                             'name': 'Blueberry Cup'},
                             {'destination_location': 
                                       {'address1': 'Teststreet 12',
                                        'address2': '',
                                        'city': 'Berlin',
                                        'country_code': 'DE',
                                        'id': 2383331012,
                                        'name': 'Test Test',
                                        'zip': '10117'}, 
                             'gift_card': False,
                             'name': 'Strawberry Cup'}]
}]}

在这种情况下,字典有4个维度,我想将dict转换为pandas数据框。我尝试了从json_normalize()到pandas.DataFrame.from_dict()的所有内容,但我没有设法到达任何地方。当我尝试将dict转换为df时,我会得到包含列表列表的列。

我的目标是每个产品都有一行。 谢谢!

期望的输出:

Created at  Email           id          Name
9/20/2016   test@test.de    4314127108  Blueberry Cup
9/20/2016   test@test.de    4314127108  Strawberry Cup

1 个答案:

答案 0 :(得分:2)

我真的不明白json_normalize()如何如此努力地失败,我有类似的数据,嵌套深度的两倍,而json_normalize()仍然可以给我一个更好的结果。

我编写了这个递归函数来用你的字典替换你的例子中的列表:

def removeList(D):
  for k in D.keys():
    if isinstance(D[k],list):
      T = {}
      for i in range(len(D[k])):
        T[str(i)] = D[k][i]
      D[k] = removeList(T)
      return D
    elif isinstance(D[k],dict):
      D[k] = removeList(D[k])
      return D
    else:
      return D

json_normalize()至少可以更好地处理结果。

但是我建议手动操作,即使它很烦人。您可以使用自己想要的结构创建自己的字典,手动将所有数据写入其中,然后将其转换为数据帧。这是检查数据一致性的好方法,并且可以完成所需的所有展平,预处理和规范化。

由于我的数据结构与您的数据类似,因此我使用的是两个步骤。在第一步中,我创建了一个扁平字典,其中没有其他字典,但仍然在一个键中有一个列表(在您的情况下为line_items)。每个列表条目也被展平为一个简单的字典。然后我从这个词典列表中创建第二个数据帧:

ListDF = pd.DataFrame.from_dict([iFr for sl in DF["List"] for iFr in sl])

由于我手动进行了所有规范化操作,因此我能够将必要的键添加到列表项中,所以现在我可以使用这些键将两个数据帧合并到我的最终数据帧中。然后我删除了List列,我的最终数据结构已经完成,我从一个可怕的嵌套字典变成了一个可以轻松使用的简单关系方案。

我认为这也适合你。