使用 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
之所以停在floors
和rules
是因为它们包含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 提取嵌套列的主要内容,如果未能解决你的问题,请参考以下文章