将多级嵌套字典转换为pandas DataFrame

时间:2014-04-11 17:36:00

标签: python dictionary pandas salesforce

我正在尝试迭代从Salesforce REST API返回的嵌套有序词典中的查询结果,并将它们转换为pandas DataFrame对象。由于返回的词典嵌套不一致,我遇到了麻烦。

例如,我有一个OrderedDict对象列表,每个对象都包含一个'Id','Email'和另一个由'url'和'type'组成的'属性'OrderedDict对象:

[OrderedDict([(u'attributes', OrderedDict([(u'type', u'someType'), (u'url', u'/someurl')])), (u'Id', u'1A'), (u'Email', u'xxxx@xxxx.com')]),…]

我想将其转换为OrderedDict对象的列表,其中所有数据字段都在同一级别(即,没有嵌套的OrderedDict对象),并且“属性”OrderedDict中包含的数据已被提出一个级别:

[OrderedDict([(u'type', u'someType'), (u'url', u'/someurl'), (u'Id', u'1A'), (u'Email', u'xxxx@xxxx.com')]),…]

理想情况下,我希望能够将数据格式化为长格式,例如对于任意数量的嵌套级别,因为它可以帮助我将数据解析为更容易操作的格式(即, pandas DataFrames)。我来自R背景,所以操作DataFrames比嵌套字典更舒服。

我一直在玩类似问题的一些已发布的解决方案,但每个似乎都解决了与我自己的用例略有不同的用例。问题是我返回的数据中嵌套字典的级别数没有一致性。如果我只是尝试将当前列表转换为pandas DataFrame,我会得到以下内容:

import pandas as pd
pd.DataFrame(salesRecords).head()

Email                   Id 
0       some@email.com  1A 
1       some@email.com  1B 
2       some@email.com  1C 
3       some@email.com  1D 
4       some@email.com  1E 
                                    attributes
0  {u'type': u'someType', u'url': u'someurl...
1  {u'type': u'someType', u'url': u'someurl...
2  {u'type': u'someType', u'url': u'someurl...
3  {u'type': u'someType', u'url': u'someurl...
4  {u'type': u'someType', u'url': u'someurl...

在这个例子中,我想要“扁平化”。属性列包含两列,包含属性数据('类型'和url')。如果有人愿意指出我正确的方向,我将不胜感激。

非常感谢!

1 个答案:

答案 0 :(得分:0)

这是我的尝试:

def flatten(d):
    '''
    Flatten an OrderedDict object
    '''
    result = OrderedDict()
    for k, v in d.items():
        if isinstance(v, dict):
            result.update(flatten(v))
        else:
            result[k] = v
    return result

讨论

  • flatten函数创建一个新的OrderedDict对象 - 扁平字典
  • 遍历每个键/值对
  • 如果值不是字典(包括OrderDict),则将键/值对复制到结果
  • 如果值是字典,包括OrderedDict,则递归调用flatten并更新结果
  • 我已经测试了这个功能,嵌套了四层深,但不能保证它没有错误
  • 在一个OrderedDict上测试flatten后,可以直接将其应用到OrderedDict列表