将巨大的JSON文件转换为csv文件

时间:2015-08-19 21:41:47

标签: python json csv

我有一个巨大的json文件要转移到csv。我在互联网上搜索了很多,我自己也尝试编写Python,但没有任何作用。我被困在这里一个星期。有人可以帮我吗? json文件格式为:

{"Gid": "5999043768223797248", 
"rights": [{"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29a6dc01000", "grantorId": "NETLIFE_B2C"}], 
"used_quota": "16.95", 
"creationtime": "2001-04-29 12:58:33", 
"devices": [{"last_connection": "2001-05-30 22:06:08", "os_version": "4.2.2", "auto_upload": "wifi", "last_upload": "2002-04-29 13:12:26", "device_name": "i-mobile i-STYLE 7.5", "platform": "unknow", "client_version": "2.0.0"}], 
"total_quota": 2.0, 
"Uid": ["666927729520"]}


{"Gid": "5999043740151320576", 
"rights": [{"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29f72c05000", "grantorId": "NETLIFE_B2C"}, 
           {"grantorContext": null, "sku": "CMO-STO-25-M", "rightId": "53b5d2d8b0400000", "grantorId": "DTN"}], 
"used_quota": "480.85", 
"creationtime": "2001-04-29 12:58:38", 
"devices": [{"last_connection": "2001-08-02 03:46:05", "os_version": "8.4", "auto_upload": "wifi", "last_upload": "2015-08-02 03:46:05", "device_name": "Nokia", "platform": "unknow", "client_version": "1.0.0"}], 
"total_quota": 27.0, 
"Uid": ["465949097714"]}


{"Gid": "5999043675907166208", 
"rights": [{"grantorContext": null, "sku": "CMO-STO-25-M", "rightId": "53b5d2e161000000", "grantorId": "DTN"}, 
           {"grantorContext": "Freemium right added by Netlife", "sku": "CMO-STO-2-FREE", "rightId": "5340e29b42805000", "grantorId": "NETLIFE_B2C"}], 
"used_quota": "8.26", 
"creationtime": "2001-04-29 12:58:35", 
"devices": [{"last_connection": "2001-04-29 13:08:24", "os_version": "4.2.2", "auto_upload": "wifi", "last_upload": "2002-04-29 13:03:25", "device_name": "Nokia V797", "platform": "unknow", "client_version": "2.0.0"}], 
"total_quota": 27.0, 
"Uid": ["666994575443"]}

3 个答案:

答案 0 :(得分:0)

我自己也有类似的文件!

它不是有效的JSON文件。它是一组连接成一个的JSON文件。来自python json.dumps文档

  

与pickle和marshal不同,JSON不是框架协议,所以试图   使用重复调用dump()来序列化多个对象   相同的fp将导致无效的JSON文件

这意味着即使它一次全部适合内存,也不能使用json.load来读取此文件,除非您在第一行之前编辑“[”并在结尾处编辑“]”每个元素之间的逗号(即“}”和“{”之间的空行

您可以使用python json模块进行操作并让它按照我认为您想要的方式进行操作,将每组七个元素按顺序读取为带有“Gid”“权限”键等的python dict。

你必须使用JSONDecoder类的raw_decode方法,该方法将在结束时停止“}”并将索引返回到它正在扫描的字符串中,这样你就可以砍掉它刚刚处理过的字符串。

因此,读取一个大块文件的大块,并在异常处理程序中尝试raw_decode一个元素。如果成功,保存解码结果,删除已成功解码的部分,然后重复。如果出现异常,请从文件中读取另一个块并附加到要解码的字符串并重复。如果仍然出现异常,那么您所在的JSON元素已损坏(或者比块大小更长,或者您无法正确处理文件末尾)。

如果您的文件小于几十(几百?)Mbytes,则编码要容易得多。然后,只需将整个事物读入一个字符串并开始从它前面扼杀JSON元素,直到除了空白之外什么都没有,或者直到你遇到解码器错误。

答案 1 :(得分:0)

这是一种蛮力的方式,因为当文件小到可以作为单个字符串处理而没有内存不足时

import json
import re

multijsons = open('file.json','r').read()

sep = re.compile( r'\}\s*\{' )
jsonlist = '[' + re.sub( sep, '}, {', multijsons ) + ']'

load =  json.loads( jsonlist)

# quick debug:
for item in load:
    print item
    print '\n---\n'

这是我使用的,因为我的文件不是那么大。考虑编码以上但不需要它,看起来好像很棘手

答案 2 :(得分:0)

这里使用re.split()稍微不那么蛮力的方式我已经测试了以下在带有8Gb RAM的core-i3上仅需几秒钟

huge="{" + "a"*1000 + "}\n"
huge = huge * 500000
len(huge)/1000000.0
# get 501.5 (Mbytes)
jsons =  re.split(r'\}\s*\{', huge)
len(s)
# get 500000, took about 2 seconds
del huge  # might be a good idea to free half a gigabyte asap.

split生成各个JSON元素,每个元素都在自己的字符串中,减去开放的大括号(第一个除外)和close卷曲(除了最后一个)。所以剩下的工作(未经测试)将是

jsons[0] = jsons[0] + '}'
n = len(jsons)
jsons[n-1] = '{' + jsons[n-1]
for i in range( 1, n-1 ): jsons[i] = '{' + jsons[i] + '}'

# i'd anticipate another couple of seconds to get here

for j in jsons:
    data = json.load( j)
    # do whatever with data
    # will take as long as it's going to take ....