我有一个大的Jsonl文件(6GB+(,需要将其转换为.csv格式。运行后:
import json
with open(root_dir + 'filename.json') as json_file:
for line in json_file:
data = json.loads(line)
print(data)
返回以下格式的许多记录:
{'url': 'https://twitter.com/CHItraders/status/945958273861275648', 'date': '2017-12-27T10:03:22+00:00', 'content': 'Why #crypto currencies like $BTC #Bitcoin are set for global domination - MUST READ! - https :// t.co/C1kEhoLaHr https :// t.co/sZT43PBDrM', 'renderedContent': 'Why #crypto currencies like $BTC #Bitcoin are set for global domination - MUST READ! - BizNews.com biznews.com/wealth-buildin…', 'id': 945958273861275648, 'username': 'CHItraders', 'user': {'username': 'CHItraders', 'displayname': 'CHItraders', 'id': 185663478, 'description': 'Options trader. Market-news. Nothing posted constitutes as advice. Do your own diligence.', 'rawDescription': 'Options trader. Market-news. Nothing posted constitutes as advice. Do your own diligence.', 'descriptionUrls': [], 'verified': False, 'created': '2010-09-01T14:52:28+00:00', 'followersCount': 1196, 'friendsCount': 490, 'statusesCount': 38888, 'favouritesCount': 10316, 'listedCount': 58, 'mediaCount': 539, 'location': 'Chicago, IL', 'protected': False, 'linkUrl': None, 'linkTcourl': None, 'profileImageUrl': 'https://pbs.twimg.com/profile_images/623935252357058560/AaeCRlHB_normal.jpg', 'profileBannerUrl': 'https://pbs.twimg.com/profile_banners/185663478/1437592670'}, 'outlinks': ['http://BizNews.com', 'https://www.biznews.com/wealth-building/2017/12/27/bitcoin-rebecca-mqamelo/#.WkNv2bQ3Awk.twitter'], 'outlinksss': 'http://BizNews.com https://www.biznews.com/wealth-building/2017/12/27/bitcoin-rebecca-mqamelo/#.WkNv2bQ3Awk.twitter', 'tcooutlinks': ['https :// t.co/C1kEhoLaHr', 'https :// t.co/sZT43PBDrM'], 'tcooutlinksss': 'https :// t.co/C1kEhoLaHr https :// t.co/sZT43PBDrM', 'replyCount': 0, 'retweetCount': 0, 'likeCount': 0, 'quoteCount': 0, 'conversationId': 945958273861275648, 'lang': 'en', 'source': '<a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>', 'media': None, 'retweetedTweet': None, 'quotedTweet': None, 'mentionedUsers': None}
由于文件的大小,我无法使用转换:
with open(root_dir + 'filename.json', 'r', encoding ='utf-8-sig') as f:
data = f.readlines()
data = map(lambda x: x.rstrip(), data)
data_json_str = "[" + ','.join(data) + "]"
newdf = pd.read_json(StringIO(data_json_str))
newdf.to_csv(root_dir + 'output.csv')
由于MemoryError。我正在尝试使用下面的生成器,并将每一行写入csv,这应该会消除MemoryError问题:
def yield_line_delimited_json(path):
"""
Read a line-delimited json file yielding each row as a record
:param str path:
:rtype: list[object]
"""
with open(path, 'r') as json_file:
for line in json_file:
yield json.loads(line)
new = yield_line_delimited_json(root_dir + 'filename.json')
with open(root_dir + 'output.csv', 'w') as f:
for x in new:
f.write(str(x))
但是,数据不会写入.csv格式。对于为什么数据没有写入csv文件的任何建议,我们将不胜感激!
生成器似乎完全多余。
with open(root_dir + 'filename.json') as old, open(root_dir + 'output.csv', 'w') as csvfile:
new = csv.writer(csvfile)
for x in old:
row = json.loads(x)
new.writerow(row)
如果一行JSON不能简单地生成一个字符串和数字数组,那么您仍然需要弄清楚如何将其从JSON内部的任何结构转换为可以有效地序列化为固定长度的字符串和数字的一维列表的结构。
如果您的JSON可以可靠地包含一个具有固定关键字-值对集的字典,那么可以尝试
from csv import DictWriter
import json
with open(jsonfile, 'r') as inp, open(csvfile, 'w') as outp:
writer = DictWriter(outp, fieldnames=[
'url', 'date', 'content', 'renderedContent', 'id', 'username',
# 'user', # see below
'outlinks', 'outlinksss', 'tcooutlinks', 'tcooutlinksss',
'replyCount', 'retweetCount', 'likeCount', 'quoteCount',
'conversationId', 'lang', 'source', 'media', 'retweetedTweet',
'quotedTweet', 'mentionedUsers'])
for line in inp:
row = json.loads(line)
writer.writerow(row)
我省略了user
字段,因为在您的示例中,该键包含一个嵌套结构,如果不进行进一步的篡改,就无法轻松地将其转换为CSV。也许您只想将user.id
提取到一个新字段user_id
中;或者您可能想将整个user
结构提升到主记录中附加列(如user_username
、user_displayname
、user_id
等(的扁平列表中?
更详细地说,CSV基本上是一个二维矩阵,其中每一行都是对应于数据中一条记录的列的一维集合,其中每列可以包含一个字符串或一个数字。每一行都需要有完全相同数量的列,尽管您可以将其中一些列留空。
JSON可以简单地转换为CSV,看起来就像
["Adolf", "1945", 10000000]
["Joseph", "1956", 25000000]
["Donald", null, 1000000]
JSON可以通过某种转换(您必须单独指定,例如上面指定的字典键排序(转换为CSV,它可能看起来像
{"name": "Adolf", "dod": "1945", "death toll": 10000000}
{"dod": "1956", "name": "Joseph", "death toll": 25000000}
{"death toll": 1000000, "name": "Donald"}
(为了让它更有趣,一个字段丢失了,字典的顺序因记录而异。这不是典型的,但肯定在有效的角落案例的范围内,Python不可能自己猜测如何处理。(
大多数真实世界的JSON比这两个简单的例子都要复杂得多,以至于我们可以说,如果不手动将您想要的数据分离并规范化为适合表示为CSV矩阵的结构,在一般情况下就不可能解决这个问题。