Json行(Jsonl)生成器转换为csv格式

ewm0tg9j  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(124)

我有一个大的Jsonl文件(6 GB+),我需要转换为.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文件的建议都非常感谢!

oxf4rvwz

oxf4rvwz1#

发电机似乎完全多余。

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结构提升到主记录中的附加列(如user_usernameuser_displaynameuser_id等)的扁平列表中?
更详细地说,CSV基本上是一个二维矩阵,其中每一行都是对应于数据中一条记录的一维列集合,每一列可以包含一个字符串或一个数字。每一行都需要有完全相同的列数,尽管您可以将其中一些列留空。
JSON可以简单地转换为CSV,如下所示

["Adolf", "1945", 10000000]
["Joseph", "1956", 25000000]
["Donald", null, 1000000]

可以通过某种转换(您必须单独指定,例如使用上面指定的字典键排序)转换为CSV的JSON可能如下所示

{"name": "Adolf", "dod": "1945", "death toll": 10000000}
{"dod": "1956", "name": "Joseph", "death toll": 25000000}
{"death toll": 1000000, "name": "Donald"}

(Just为了使它更有趣,一个字段丢失了,并且字典顺序从一条记录到下一条记录是不同的。这不是典型的,但绝对在有效的极端情况的范围内,Python不可能自己猜测如何处理。)
大多数实际的JSON都比这两个简单的例子要复杂得多,以至于我们可以说,在一般情况下,如果不手动分离数据并将其规范化为适合表示为CSV矩阵的结构,这个问题是不可能解决的。

相关问题