在 Python 中规范化嵌套列表时出错

Posted

技术标签:

【中文标题】在 Python 中规范化嵌套列表时出错【英文标题】:Getting error to normalize nested list in Python 【发布时间】:2019-02-28 03:10:44 【问题描述】:

我有一个带有字典的嵌套列表。以下只是列表的第一个元素

    'id': 'abcde',
     'authorization': None,
     'operation_type': 'xx',
     'method': 'card',
     'transaction_type': 'asd',
     'card': 'type': 'dd',
      'brand': 'vv',
      'address': 'line1': 'xxxxxxx',
       'line2': '',
       'line3': '',
       'state': 'xx',
       'city': 'xxx',
       'postal_code': '12345',
       'country_code': 'xx',
      'card_number': '123456XXXXXX7890',
      'holder_name': 'name user,
      'expiration_year': '20',
      'expiration_month': '02',
      'allows_charges': True,
      'allows_payouts': True,
      'bank_name': 'abc bank',
      'bank_code': '000',
     'status': 'fgh',
     'conciliated': True,
     'creation_date': '2018-09-23T23:58:17-05:00',
     'operation_date': '2018-09-23T23:58:17-05:00',
     'description': 'asdmdefdsa',
     'error_message': 'sdaskjflj',
     'order_id': 'ashdgjasdfhk',
     'amount': 418.0,
     'customer': 'name': 'abc',
      'last_name': 'xyz',
      'email': 'abcdef@hotmail.com',
      'phone_number': '12345678',
      'address': None,
      'creation_date': '2018-09-23T23:58:18-05:00',
      'external_id': None,
      'clabe': None,
     'fee': 'amount': 0.56, 'tax': 0.91, 'currency': 'XXX',
     'currency': 'XXX',
'id': 'abcde',
     'authorization': None,
     'operation_type': 'xx',
     'method': 'card',
     'transaction_type': 'asd',
     'card': 'type': 'dd',
      'brand': 'vv',
      'address': 'line1': 'xxxxxxx',
       'line2': '',
       'line3': '',
       'state': 'xx',
       'city': 'xxx',
       'postal_code': '12345',
       'country_code': 'xx',
      'card_number': '123456XXXXXX7890',
      'holder_name': 'name user,
      'expiration_year': '20',
      'expiration_month': '02',
      'allows_charges': True,
      'allows_payouts': True,
      'bank_name': 'abc bank',
      'bank_code': '000',
     'status': 'fgh',
     'conciliated': True,
     'creation_date': '2018-09-23T23:58:17-05:00',
     'operation_date': '2018-09-23T23:58:17-05:00',
     'description': 'asdmdefdsa',
     'error_message': 'sdaskjflj',
     'order_id': 'ashdgjasdfhk',
     'amount': 418.0,
     'customer': 'name': 'abc',
      'last_name': 'xyz',
      'email': 'abcdef@hotmail.com',
      'phone_number': '12345678',
      'address': None,
      'creation_date': '2018-09-23T23:58:18-05:00',
      'external_id': None,
      'clabe': None,
     'fee': 'amount': 0.56, 'tax': 0.91, 'currency': 'XXX',
     'currency': 'XXX'

我想将数据标准化为数据框。我将代码编写为:json_normalize(d)。但我收到以下错误:

----------------------------------- ---------------------------- KeyError Traceback(最近一次调用 最后)在() ----> 1 df = json_normalize(数据)

/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py json_normalize(数据,记录路径,元,元前缀,记录前缀, 错误,九月) 201 # TODO: 处理列表的记录值,至少错误 202#合理 --> 203 数据=nested_to_record(数据,sep=sep) 204 返回数据帧(数据) 205 elif not isinstance(record_path, list):

/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py nested_to_record(ds,前缀,sep,级别) 86 其他: 87 v = new_d.pop(k) ---> 88 new_d.update(nested_to_record(v, newkey, sep, level + 1)) 89 new_ds.append(new_d) 90

/anaconda3/lib/python3.6/site-packages/pandas/io/json/normalize.py nested_to_record(ds,前缀,sep,级别) 82 new_d[新键] = v 83 if v is None: # 如果值为None,则弹出键 ---> 84 new_d.pop(k) 85 继续 86 其他:

KeyError: '地址'

我明白,因为地址没有,代码给了我错误。但我不知道如何解决它。在这方面的任何帮助将不胜感激。提前致谢。 (请注意数据为虚拟数据)

【问题讨论】:

【参考方案1】:

字典格式错误。首先,你有如下几行:

'holder_name': 'name user,

其中值'name user 不是有效字符串,因为它没有被右侧的单引号字符括起来。

其次,在您的代码中,您有一个列表的两个元素,即两个字典,每个字典都以 'id': ... 开头,而不是声称的单个元素。

在两个字典中修复'holder_name 的值并使其成为一个包含两个成员的列表后,您可以继续使用json_normalize,您将获得如下输出(打印在标准输出中):

   amount authorization card.address.city card.address.country_code    ...        operation_type      order_id status transaction_type 0  
418.0          None               xxx                        xx       ...                    xx  ashdgjasdfhk    fgh              asd 1  
418.0          None               xxx                        xx       ...                    xx  ashdgjasdfhk    fgh              asd

[2 rows x 42 columns]

【讨论】:

【参考方案2】:

我试图重现此错误,但无法重现。在创建 python3 venv 并使用 pip 安装 pandas 后,我将您的代码(python 字典而不是 json - 我的错误,感谢@AlessandroCosentino +1 从我这里)复制到编辑器,发现第 16 行和第 56 行缺少单引号 'holder_name': 'name user, 并且应该是 'holder_name': 'name user',

from pandas.io.json import json_normalize
data = 'id': 'abcde',
        'authorization': None,
        'operation_type': 'xx',
        'method': 'card',
        'transaction_type': 'asd',
        'card': 'type': 'dd',
        'brand': 'vv',
        'address': 'line1': 'xxxxxxx',
        'line2': '',
        'line3': '',
        'state': 'xx',
        'city': 'xxx',
        'postal_code': '12345',
        'country_code': 'xx',
        'card_number': '123456XXXXXX7890',
        'holder_name': 'name user',
        'expiration_year': '20',
        'expiration_month': '02',
        'allows_charges': True,
        'allows_payouts': True,
        'bank_name': 'abc bank',
        'bank_code': '000',
        'status': 'fgh',
        'conciliated': True,
        'creation_date': '2018-09-23T23:58:17-05:00',
        'operation_date': '2018-09-23T23:58:17-05:00',
        'description': 'asdmdefdsa',
 'error_message': 'sdaskjflj',
 'order_id': 'ashdgjasdfhk',
 'amount': 418.0,
 'customer': 'name': 'abc',
  'last_name': 'xyz',
  'email': 'abcdef@hotmail.com',
  'phone_number': '12345678',
  'address': None,
  'creation_date': '2018-09-23T23:58:18-05:00',
  'external_id': None,
  'clabe': None,
 'fee': 'amount': 0.56, 'tax': 0.91, 'currency': 'XXX',
 'currency': 'XXX',
  'id': 'abcde',
 'authorization': None,
 'operation_type': 'xx',
 'method': 'card',
 'transaction_type': 'asd',
 'card': 'type': 'dd',
  'brand': 'vv',
  'address': 'line1': 'xxxxxxx',
   'line2': '',
   'line3': '',
   'state': 'xx',
   'city': 'xxx',
   'postal_code': '12345',
   'country_code': 'xx',
  'card_number': '123456XXXXXX7890',
  'holder_name': 'name user',
  'expiration_year': '20',
  'expiration_month': '02',
  'allows_charges': True,
  'allows_payouts': True,
  'bank_name': 'abc bank',
  'bank_code': '000',
 'status': 'fgh',
 'conciliated': True,
 'creation_date': '2018-09-23T23:58:17-05:00',
 'operation_date': '2018-09-23T23:58:17-05:00',
 'description': 'asdmdefdsa',
 'error_message': 'sdaskjflj',
 'order_id': 'ashdgjasdfhk',
 'amount': 418.0,
 'customer': 'name': 'abc',
  'last_name': 'xyz',
  'email': 'abcdef@hotmail.com',
  'phone_number': '12345678',
  'address': None,
  'creation_date': '2018-09-23T23:58:18-05:00',
  'external_id': None,
  'clabe': None,
 'fee': 'amount': 0.56, 'tax': 0.91, 'currency': 'XXX',
 'currency': 'XXX'


print(json_normalize(data))

输出是这样的

这可以通过使用带有 python 高亮显示的智能编辑器(例如 SublimeText)轻松避免。你用的是什么编辑器?

【讨论】:

我正在使用 jupyter notebook 尝试使用 JSON 格式化程序和验证器 - jsonformatter.curiousconcept.com @NikolaosDalezios JSON 字符串与 Python 字典不同,JSON 格式化程序在这里没有帮助(例如,Python 使用 None 对象,JSON 使用 null)。 OP 在这里需要的是支持 Python 语法的编辑器,而不是 JSON 验证器。 你是对的@AlessandroCosentino,但在这种情况下,我认为问题是 JSON 字符串格式错误,而不是 None 或 Null 值 - 一个常见的语法错误。 @NikolaosDalezios None/Null 只是一个例子。我的意思是,我们在这里讨论的是 Python 语法,而不是 JSON 语法。

以上是关于在 Python 中规范化嵌套列表时出错的主要内容,如果未能解决你的问题,请参考以下文章

Python编码规范

Python开发规范

Python开发规范

如何通过 Python Pandas 正确规范化 json

用嵌套列表和嵌套字典列表展平一个非常大的 Json

如何将嵌套的 JSON 键规范化为 pandas 数据帧