使用 Python 提取嵌套列

Posted

技术标签:

【中文标题】使用 Python 提取嵌套列【英文标题】:Nested column extraction using Python 【发布时间】:2019-04-10 04:17:47 【问题描述】:

我花了几个小时试图取消嵌套来自 json 文件的数据框中的列,但仍然无法使其工作。

我使用 GraphQl 查询了一个网站并将响应加载到变量 json 中:

json = resp.json()

接下来,我使用 json_normalize 将数据加载到数据框中:

df = pd.DataFrame.from_dict(json_normalize(resp.json()), orient='columns')

我重命名了列。

但是,数据框中仍有嵌套列 - 即“规则”和“楼层”:

然后我尝试通过我在 *** 上以及互联网上其他地方看到的几种方法来取消嵌套列:

我尝试了不同版本的嵌套列 json_normalize 以及元数据,但调用特定值的方法都不起作用:

  json_normalize(json, ['floors', ['units'],['features']])

还有这个:

 json_normalize(data=json, record_path=['floors', 'units','features'])

然而,在大多数情况下,我得到了 TypeError: string indices must be integers。

我尝试将值分别分配给列,但对于其中一些为 NULL 的情况,这失败了

df['pets allowed'] = json['data']['offerAggregate']['property_aggregate']['property']['rules']['code' == 'pets-allowed']['exists']

我也尝试通过“代码”等关键字拆分列,但这仅返回 Null

理想情况下,我想让选项 #1 起作用,但我确实尝试了这么多版本,但仍然没有结果,因为我不确定如何正确定义嵌套列的路径。

这是完整的架构:

'data': 'offerAggregate': 'accommodation_offer': 'contract': 'type': 'fortnight',
     'exclusive': False,
     'is_instant_booking': False,
     'commission': 0.08,
     'deposit': 'pay_to': 'accommodation-provider',
      'type': 'equal-to-first-payment',
      'value': 'amount': 0, 'currency_code': '',
     'admin_fee': 'exact_value': True,
      'value': 'amount': 0, 'currency_code': 'EUR',
     'fixed_unitary': 'extra_per_guest': 'amount': 0, 'currency_code': '',
    'reference_price': 'amount': '25000', 'currency_code': 'EUR',
    'requisites': 'conditions': 'cancellation_policy': 'moderate',
      'minimum_nights': 27,
      'max_guests': 2,
    'costs': 'bills': 'water': 'included': True,
      'electricity': 'included': True,
      'gas': 'included': True,
      'internet': 'included': True,
     'services': 'cleaning': 'periodicity': 'weekly',
   'accommodation_provider': 'stats': 'bookings': 'accepted': 'total': 2,
      'requested': 'total': 10,
      'rejected': 'total': 1,
      'confirmed': 'total': 0,
    'created': 'at': '2018-11-02 16:51:22',
   'property_aggregate': 'property': 'id': '114087',
     'landlord_resident': 'gender': '', 'age_range': '', 'occupation': '',
     'floors': ['units': ['features': ['Code': 'fridge', 'Exists': True,
          'Code': 'freezer', 'Exists': True,
          'Code': 'oven', 'Exists': True,
          'Code': 'stove', 'Exists': True,
          'Code': 'washing-machine', 'Exists': True,
          'Code': 'window', 'Exists': True,
          'Code': 'balcony', 'Exists': False,
          'Code': 'table', 'Exists': True,
          'Code': 'chairs', 'Exists': True],
        'features': ['Code': 'bathtub', 'Exists': False,
          'Code': 'shower', 'Exists': True,
          'Code': 'sink', 'Exists': True,
          'Code': 'toilet', 'Exists': True,
          'Code': 'window', 'Exists': True],
        'features': ['Code': 'wardrobe', 'Exists': True,
          'Code': 'chest-of-drawers', 'Exists': False,
          'Code': 'desk', 'Exists': True,
          'Code': 'chairs', 'Exists': True,
          'Code': 'sofa', 'Exists': False,
          'Code': 'sofa-bed', 'Exists': False,
          'Code': 'window', 'Exists': True,
          'Code': 'balcony', 'Exists': False,
          'Code': 'tv', 'Exists': False,
          'Code': 'lock', 'Exists': True],
        'features': ['Code': 'wardrobe', 'Exists': True,
          'Code': 'chest-of-drawers', 'Exists': False,
          'Code': 'desk', 'Exists': True,
          'Code': 'chairs', 'Exists': True,
          'Code': 'sofa', 'Exists': False,
          'Code': 'sofa-bed', 'Exists': False,
          'Code': 'window', 'Exists': True,
          'Code': 'balcony', 'Exists': True,
          'Code': 'tv', 'Exists': False,
          'Code': 'lock', 'Exists': True],
        'features': ['Code': 'wardrobe', 'Exists': True,
          'Code': 'chest-of-drawers', 'Exists': False,
          'Code': 'desk', 'Exists': False,
          'Code': 'chairs', 'Exists': False,
          'Code': 'sofa', 'Exists': False,
          'Code': 'sofa-bed', 'Exists': False,
          'Code': 'window', 'Exists': True,
          'Code': 'balcony', 'Exists': False,
          'Code': 'tv', 'Exists': False,
          'Code': 'lock', 'Exists': True],
        'features': ['Code': 'wardrobe', 'Exists': True,
          'Code': 'chest-of-drawers', 'Exists': False,
          'Code': 'desk', 'Exists': False,
          'Code': 'chairs', 'Exists': False,
          'Code': 'sofa', 'Exists': False,
          'Code': 'sofa-bed', 'Exists': False,
          'Code': 'window', 'Exists': True,
          'Code': 'balcony', 'Exists': True,
          'Code': 'tv', 'Exists': False,
          'Code': 'lock', 'Exists': True]]],
     'rules': ['code': 'overnight-guests-allowed', 'exists': False,
      'code': 'pets-allowed', 'exists': False,
      'code': 'smoking-allowed', 'exists': False],
     'typology': 'area': 0,
      'accommodation_type_code': 'private',
      'type_code': 'apartment',
      'number_of_bedrooms': 4,
      'number_of_bathrooms': 1,
     'location': 'neighborhood_id': 229,
      'geo': 'latitude': 38.7514768, 'longitude': -9.2031683,
      'address': 'postal_code': '1500-109',
     'verification': 'verified': True

提前感谢您的宝贵时间!非常感谢任何帮助!

【问题讨论】:

我认为你真的想用 pd.read_json 代替:pandas.pydata.org/pandas-docs/stable/generated/… 嘿,凯文,我尝试使用 pd.read_json,但我无法应用它,因为我的对象是 Python 字典。我没有找到将请求响应转换为真正 JSON 的方法。命令 resp.json() 似乎已将其转换为 Python 对象。 这会返回一个包含 2 列的数据框:“index”列中的“offerAggregate”和“data”列中的整个字典的其余部分 【参考方案1】:

json_normalize 之所以停在floorsrules 是因为它们包含lists 而不是dictionaries,而这正是json_normalize 所等待的。

要规范化此 json,您需要将这些列表转换为类似字典的结构。因此,例如对于规则而不是这种结构:

['code': 'overnight-guests-allowed', 'exists': False,
  'code': 'pets-allowed', 'exists': False,
  'code': 'smoking-allowed', 'exists': False]

你会想要这个结构:

'overnight-guests-allowed': False,
 'pets-allowed': False,
 'smoking-allowed': False

【讨论】:

@HannahKorts 很高兴听到这个消息!

以上是关于使用 Python 提取嵌套列的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 从 JSON 嵌套列表和字符串数组中提取值

MySQL 嵌套 JSON 列搜索和提取子 JSON

从 Python 中的嵌套 Json 中提取信息

从 JSON 中提取深度嵌套的值

Python从嵌套字典中提取正确的数据

Scrapy - 使用 xPathSelector 提取嵌套的“img src”