首页 > 解决方案 > 循环 JSON 到附加 CSV 的多文件处理

问题描述

我无法使用 for 循环的正确语法一次打开多个 gzip 行 json 文件,处理文件以仅提取某些键值对,然后保存到附加的单个 csv 文件。gzip 文件很大。

for循环应该如何嵌套一次打开,处理,写入一个文件?

我似乎在写入之前一次打开/加载所有文件,然后最终崩溃内存或一次成功打开 1 个但在写入阶段出现 I/O 错误,因为 outfile 已关闭。

directory = r"*/mydirectory*"

field_names = [
    "id",
    "created_at",
    "user_screen_name",
    "text",
    "lang",
    "place_country_code",
    "place_name",
    "coordinates",
    "entities_user_mentions_screen_name",
]

tweets = []

for filename in os.scandir(directory):
    if filename.path.endswith(".gz") and filename.is_file():
        with gzip.open(filename, 'r') as infile, \
             open('clean_tweet_all_data.csv', 'a', newline="", encoding='utf-8') as outfile:
            for line in infile:
                tweets.append(json.loads(line)),
                csv_output = csv.DictWriter(outfile, delimiter=",", fieldnames=field_names,
                                            extrasaction="ignore")
                if outfile.tell() == 0:
                    csv_output.writeheader(),
                    csv_output.writerows(get_arrays(entry) for entry in tweets)


infile.close()
outfile.close()

该函数get_arrays(entry)将 json 文件展平,因此field_names用于选择键值对的列表运行良好。

标签: pythonjsoncsvfor-loop

解决方案


我看到了三个问题,但我不知道这是否会导致您描述的问题

  1. 列表一直在增长,这可能会导致内存错误,你应该在写完推文后tweets重置它( )tweets = []

  2. 最后不需要infile.close()and outfile.close(),这已经由上下文管理器 ( with open ...)

  3. 您只写入文件一次,因为您只写入 if outfile.tell() == 0,也许您打算将最后一行放在if块之外?


推荐阅读