用 Python 编写大型 CSV 的最快方法

新手上路,请多包涵

我想在 csv 文件中写入一些随机样本数据,直到它达到 1GB 大。以下代码正在运行:

 import numpy as np
import uuid
import csv
import os
outfile = 'data.csv'
outsize = 1024 # MB
with open(outfile, 'ab') as csvfile:
    wtr = csv.writer(csvfile)
    while (os.path.getsize(outfile)//1024**2) < outsize:
        wtr.writerow(['%s,%.6f,%.6f,%i' % (uuid.uuid4(), np.random.random()*50, np.random.random()*50, np.random.randint(1000))])

如何更快地获得它?

原文由 Balzer82 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 510
2 个回答

删除所有不必要的东西,因此它应该更快更容易理解:

 import random
import uuid
outfile = 'data.csv'
outsize = 1024 * 1024 * 1024 # 1GB
with open(outfile, 'ab') as csvfile:
    size = 0
    while size < outsize:
        txt = '%s,%.6f,%.6f,%i\n' % (uuid.uuid4(), random.random()*50, random.random()*50, random.randrange(1000))
        size += len(txt)
        csvfile.write(txt)

原文由 Daniel 发布,翻译遵循 CC BY-SA 3.0 许可协议

这个问题似乎主要是 IO 绑定的。您可以通过以更大的块写入文件而不是一次写入一行来稍微改进 I/O:

 import numpy as np
import uuid
import os
outfile = 'data-alt.csv'
outsize = 10 # MB
chunksize = 1000
with open(outfile, 'ab') as csvfile:
    while (os.path.getsize(outfile)//1024**2) < outsize:
        data = [[uuid.uuid4() for i in range(chunksize)],
                np.random.random(chunksize)*50,
                np.random.random(chunksize)*50,
                np.random.randint(1000, size=(chunksize,))]
        csvfile.writelines(['%s,%.6f,%.6f,%i\n' % row for row in zip(*data)])

您可以试验 chunksize(每个块写入的行数)以查看在您的机器上最有效的方法。


这是一个基准测试,将上面的代码与您的原始代码进行比较,将 outsize 设置为 10 MB:

 % time original.py

real    0m5.379s
user    0m4.839s
sys 0m0.538s

% time write_in_chunks.py

real    0m4.205s
user    0m3.850s
sys 0m0.351s

所以这比原始代码快了大约 25%。


附言。我尝试用对所需总行数的估计替换对 os.path.getsize 的调用。不幸的是,它并没有提高速度。由于表示最终 int 所需的字节数各不相同,因此估计也不准确——也就是说,它不能完美地复制原始代码的行为。所以我把 os.path.getsize 留在原地。

原文由 unutbu 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏