【问题标题】:Difficult nested dictionary to Pandas DataframePandas Dataframe 的困难嵌套字典
【发布时间】:2019-12-01 06:41:18
【问题描述】:

这是我烦人的嵌套字典:


 "data": [

{
 'type': 'a',
 'id': '3',
 'attributes': {'name': 'Alexander',
  'address': 'Ree 25',
  'postalCode': '3019 VM',
  'place': 'Amsterdam',
  'company': 'Pizza BV',
  'phoneNumbers': [{'description': 'general', 'phoneNumber': '+31104136911'}],
  'locationCode': 'DURTM',
  'website': 'http://www.pizzabv.nl',
  'primaryEmail': 'info@pizzabv.nl',
  'secondaryEmail': '',
  'geoLocation': {'type': 'Point',
    'coordinates': [16.309702884655767, 31.879930329139634]
 }
},
 'relationships': [],
 'links': {'self': 'www.homepage.nl'
  }
},

{
 'type': 'b',
 'id': '7',
 'attributes': {'name': 'Sam',
  'address': 'Zee 15',
  'postalCode': '2019 AM',
  'place': 'Groningen',
  'company': 'Salami BV',
  'phoneNumbers': [{'description': 'specific', 'phoneNumber': '+31404136121'}],
  'locationCode': 'SWSTM',
  'website': 'http://www.salamibv.nl',
  'primaryEmail': 'info@salamibv.nl',
  'secondaryEmail': '',
  'geoLocation': {'type': 'Point',
   'coordinates': [18.309702884655767, 34.879930329139634]
 }
},
 'relationships': [],
 'links': {'self': 'www.homepage.nl'
 }
}
]

这就是我想要的数据框:


type | id | name | address | postalCode | ... | type | coordinates | relationships | links
...    ...   ...     ...        ...       ...    ...      ...            ...          ...

因此,必须将不同的底层词典上移一层。首先必须删除属性,并且必须将基础值上移一层。

另外,descriptionphoneNumber 必须上移一层,然后 phoneNumbers 才能删除。

此外,关于 typeid 的所有信息都应放在一行中。

我不知道该怎么做。我尝试了以下几种方法:

terminals = pd.DataFrame.from_dict(data, orient='columns')
terminals.reset_index(level=0, inplace=True)
terminals.head()

但这在 Pandas 数据框的一个单元格中为我提供了完整的字典。

希望有人能帮帮我。

【问题讨论】:

    标签: python pandas dataframe dictionary nested


    【解决方案1】:

    您必须隐藏您的数据。您可以使用递归函数来做到这一点,例如:

    def denest(x, parent=None, d=None):
        if d is None:
            d = {}
        for k, v in x.items():
            if isinstance(v, dict):
                denest(v, parent=(parent or []) + [k], d=d)
            elif isinstance(v, (list, tuple)):
                for j, item in enumerate(v):
                    if isinstance(item, dict):
                        denest(item, parent=(parent or []) + [k, j], d=d)
                    else:
                         d[tuple((parent or []) + [k, j])] = item
            else:
                d[tuple((parent or []) + [k])] = v
        return d
    

    然后,假设data 是一个字典列表,您可以像这样简单地创建一个数据框:

    pd.DataFrame([denest(i) for i in data])
    
      (attributes, address) (attributes, company)  (attributes, geoLocation, coordinates, 0)  (attributes, geoLocation, coordinates, 1) (attributes, geoLocation, type) (attributes, locationCode) (attributes, name) (attributes, phoneNumbers, 0, description) (attributes, phoneNumbers, 0, phoneNumber) (attributes, place) (attributes, postalCode) (attributes, primaryEmail) (attributes, secondaryEmail)   (attributes, website) (id,)    (links, self) (type,)
    0                Ree 25              Pizza BV                                  16.309703                                   31.87993                           Point                      DURTM          Alexander                                    general                               +31104136911           Amsterdam                  3019 VM            info@pizzabv.nl                                http://www.pizzabv.nl     3  www.homepage.nl       a
    1                Zee 15             Salami BV                                  18.309703                                   34.87993                           Point                      SWSTM                Sam                                   specific                               +31404136121           Groningen                  2019 AM           info@salamibv.nl                               http://www.salamibv.nl     7  www.homepage.nl       b
    

    如果您愿意,您可以从这里重命名列和/或将它们转换为多索引数据框等。

    【讨论】:

      【解决方案2】:

      定义一个函数,将字典解析为扁平结构,然后在将其传递给数据帧构造函数之前应用它

      def parse(dict_)
          di = dict_.copy()  # weak copy the dictionary so you don't modify the original dicts
      
          # bring attributes up a level
          di.update(di['attributes'])
          del di['attributes']
      
          # etc...
          return di
      
      df = pd.DataFrame(map(parse, data))
      
      
      

      【讨论】:

        猜你喜欢
        • 2022-01-01
        • 2022-01-02
        • 1970-01-01
        • 2020-02-18
        • 2017-12-26
        • 1970-01-01
        • 2019-11-16
        • 2016-07-24
        • 2015-08-03
        相关资源
        最近更新 更多