2015-01-01 72 views
4

我想在csv文件中编写一些随机样本数据,直到它达到1GB大为止。以下代码正在工作:使用Python编写大型CSV文件的最快方法

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))])  

如何让它更快?

+2

为什么你用numpy标记这个问题,但不要使用它(它不需要随机数)?为什么要创建一个csv-writer但每行只写一个字符串?没有给出,文件大小在文件未关闭时更新。自己计算大小,不要使用'getsize',也要快得多。 – Daniel

回答

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) 
+0

是len(txt)==文件大小?而'random.randint(1000)'需要2个参数。 – Balzer82

+0

randint - > randrange。而'len(txt)'是一行的长度。 – Daniel

+0

好的。但是一行的长度或行长的总和不是文件大小。顺便说一句,你的代码不会更快。试试看。 – Balzer82

4

的问题似乎主要是IO的限制。您可以通过在更大的块写入文件,而不是在一个时间写一行提高I/O位:

import numpy as np 
import uuid 
import csv 
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%。


PS。我试着用所估计的总行数来替换os.path.getsize的调用。不幸的是,它并没有提高速度。由于表示最终整数所需的字节数有所不同,所以估计也是不精确的 - 也就是说,它不能完美地复制原始代码的行为。所以我离开了os.path.getsize

相关问题