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

标签 python json csv jsonlines

我有一个很大的 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')

由于内存错误。我正在尝试使用下面的生成器并将每一行写入 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_usernameuser_displaynameuser_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 都比这些简单的示例复杂得多,以至于我们可以说,如果您不手动分离并规范化 JSON,则在一般情况下该问题是不可能解决的。将您想要的数据转换为适合表示为 CSV 矩阵的结构。

关于python - Json 行 (Jsonl) 生成器转为 csv 格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65338470/

相关文章:

python - 我如何在这个简单的图中找到某个节点的所有传入弧/边

python - reportlab 图片转 PDF : "please call tobytes()"

php - Json - Mysql 字符集问题

python - 当我尝试使用 pip install psycopg2 安装 psycopg2 时出现此错误。我应该怎么办?

Python - Matplotlib/matplotlib.cbook.TimeoutError : LOCKERROR

c# - JSON.net 直接从 oledbconnection 序列化

java - Asynctask创建问题

python - 将 csv 文件传递​​到 Python 函数中的问题

python - 在 CSV 文件中存储和检索 bool 值的便捷方法是什么

php - 如何将此数据列表压缩到一个字段中?