将json数据转换为dataframe或csv

时间:2014-11-25 02:25:39

标签: python json

我正在尝试将json文件转换为表格格式,其中我在第一行中包含不同的字段,并在其余行中包含这些字段的相应数据。

将我的json转换为文本,这就是数据的样子(只是添加一些上下文的小样本)

{" business_id":" O_X3PGhk3Y5JWVi866qlJg"," full_address":" 1501 W Bell Rd \ nPhoenix,AZ 85023" ,"小时":{"星期一":{"关闭":" 18:00","打开": " 11:00"},"星期二":{"关闭":" 18:00","打开" :" 11:00"},"星期五":{"关闭":" 18:00","打开&#34 ;:" 11:00"},"星期三":{"关闭":" 18:00","打开&# 34;:" 11:00"},"星期四":{"关闭":" 18:00","打开& #34;:" 11:00"},"星期天":{"关闭":" 18:00","打开":" 11:00"},"星期六":{"关闭":" 18:00",&#34 ;打开":" 11:00"}},"打开":真实,"类别":["积极生活", "艺术&娱乐","体育场馆& Arenas","赛马"],"城市":"凤凰城"," review_count":29,"名称& #34;:"草坪天堂赛马场","街区":[],"经度":-112.0923293,"州":& #34; AZ","明星":4.0,"纬度":33.638572699999997,"属性":{"外卖" :false," Wi-Fi":"免费"," Good For":{"甜点":false," latenight& #34;:false,"午餐":false,"晚餐":false,"早午餐":false,"早餐":false} ,"噪音水平":"平均","采取预订":是,"有电视":是,"交付&# 34;:假,"氛围":{"浪漫":假,"亲密":假,"旅游观光":假,&# 34;时髦":假,"潜水":假,"优雅":假,"流行":假,"高档" :false," casual":false}," Parking":{" garage":false, " street":false," validated":false," lot":true," valet":true},"轮椅无障碍":真实,"户外座位":真实,"服装":"休闲","酒精":" full_bar"," Waiter Service":true,"接受信用卡":true,"对孩子有益":false," Good For Groups& #34;:是的,"价格范围":2},"输入":"业务"}

我在使用初始代码时遇到了一些问题:

import json
data=json.load(open('yelp_academic_dataset_user.json'))

我收到以下错误。

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-fbf46968052d> in <module>()
      1 
      2 import json
----> 3 data=json.load(open('yelp_academic_dataset_user.json'))

C:\Users\ankit.gadodia\AppData\Local\Continuum\Anaconda\lib\json\__init__.pyc in load(fp, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    288         parse_float=parse_float, parse_int=parse_int,
    289         parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
--> 290         **kw)
    291 
    292 

C:\Users\ankit.gadodia\AppData\Local\Continuum\Anaconda\lib\json\__init__.pyc in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    336             parse_int is None and parse_float is None and
    337             parse_constant is None and object_pairs_hook is None and not kw):
--> 338         return _default_decoder.decode(s)
    339     if cls is None:
    340         cls = JSONDecoder

C:\Users\ankit.gadodia\AppData\Local\Continuum\Anaconda\lib\json\decoder.pyc in decode(self, s, _w)
    367         end = _w(s, end).end()
    368         if end != len(s):
--> 369             raise ValueError(errmsg("Extra data", s, end, len(s)))
    370         return obj
    371 

ValueError: Extra data: line 2 column 1 - line 70818 column 1 (char 259 - 26982351)

有人可以解释我如何纠正这个或其他一些方式开始。到目前为止我见过的所有其他示例都涉及json.load函数。 我甚至尝试过file.read()函数,但这也是一个错误

1 个答案:

答案 0 :(得分:2)

这里有两个可能的问题。


首先,在您发布的实际数据中,假设输出中的\n实际上是换行符,而不是后跟n的反斜杠,这是无效的JSON,并且您已经可能在输出和输入之间的某处损坏了它。

如果你能回到原始数据,那将是最好的。

如果不能,您可以尝试转义控制字符,例如,通过编码到unicode-escape。对于您现有的示例以及大量现实生活中的数据,这些数据将恢复原始JSON,但有些边缘情况不会。但

如果您的文件足够小以加载到内存中,最简单的方法是:

with open('yelp_academic_dataset_user.json') as f:
    contents = f.read().encode('unicode-escape').decode('ascii')
data = json.loads(contents)

如果您的文件变得庞大,请参阅codecs模块,了解如何在文件前链接编码器和解码器,以便您可以即时转换。


其次,“第2行第1列”听起来很可疑,就像文件中有一个JSON对象流,而不是单个JSON对象。在您向我们展示的示例中看不到此问题,但是您的某些文件可能只有一个JSON对象,而其他文件只有两个或更多。

同样,如果您可以修复数据(例如,使其成为单个JSON数组,而不是单独的对象流),那么这始终是最佳解决方案。

如果没有,则无法使用json.load解析该问题,因为JSON对象流不是JSON对象。您需要做的是使用raw_decode拉出JSON对象,直到完成为止:

with open('yelp_academic_dataset_user.json') as f:
    contents = f.read()
decoder = json.JSONDecoder()
while contents:
    data, idx = decoder.raw_decode(contents)
    contents = contents[idx:]

当然,在这种情况下,您必须使用data循环中的每个for,或将它们累积到某个集合中。

如果您知道每个JSON对象本身都在一行上,您可以做一些更简单(也更高效)的事情:

with open('yelp_academic_dataset_user.json') as f:
    for line in f:
        data = json.loads(line)

但是因为在JSON对象中间有新行是完全合法的(只是不在字符串内部),所以这可能非常脆弱。