2017-10-10 26 views
1

私は500万行のcsvファイルを持っています。 ファイルをユーザーが指定した数の行に分割します。大きなcsvファイルをPythonで分割する

次のコードを作成しましたが、実行に時間がかかりすぎました。誰もコードの最適化を助けることができます。

import csv 
print "Please delete the previous created files. If any." 

filepath = raw_input("Enter the File path: ") 

line_count = 0 
filenum = 1 
try: 
    in_file = raw_input("Enter Input File name: ") 
    if in_file[-4:] == ".csv": 
     split_size = int(raw_input("Enter size: ")) 
     print "Split Size ---", split_size 
     print in_file, " will split into", split_size, "rows per file named as OutPut-file_*.csv (* = 1,2,3 and so on)" 
     with open (in_file,'r') as file1: 
      row_count = 0 
      reader = csv.reader(file1) 
      for line in file1: 
       #print line 
      with open(filepath + "\\OutPut-file_" +str(filenum) + ".csv", "a") as out_file: 
       if row_count < split_size: 
        out_file.write(line) 
        row_count = row_count +1 
       else: 
        filenum = filenum + 1 
        row_count = 0 
      line_count = line_count+1 
     print "Total Files Written --", filenum 
    else: 
     print "Please enter the Name of the file correctly."   
except IOError as e: 
    print "Oops..! Please Enter correct file path values", e 
except ValueError: 
    print "Oops..! Please Enter correct values" 

私も

+5

lakhsよりも従来のユニットはどうですか?;) – liborm

+0

別のファイルポインタを使って異なるポイントを探して、それらをcoルーチン/ geventで並列に使うのはどうですか? – SRC

+0

私はまだそれを試していない。同じものを手伝ってもらえますか?マルチスレッドまたはマルチタスクがここで役立つでしょうか。 – user2597209

答えて

2

Oups "オープンで" なしで試してみました!

... 
    with open (in_file,'r') as file1: 
     row_count = 0 
     #reader = csv.reader(file1) # unused here 
     out_file = open(filepath + "\\OutPut-file_" +str(filenum) + ".csv", "a") 
     for line in file1: 
      #print line 
      if row_count >= split_size: 
       out_file.close() 
       filenum = filenum + 1 
       out_file = open(filepath + "\\OutPut-file_" +str(filenum) + ".csv", "a") 
       row_count = 0 
      out_file.write(line) 
      row_count = row_count +1 
      line_count = line_count+1 
     ... 

理想的には、あなたも、tryブロックの前にout_file = Noneを初期化する必要がありますし、クリーン性を確保:それは高価な操作であるときは、一貫して、それぞれの行に出力ファイルを再度開いている...あなたのコードはなるかもしれない可能性がありexceptブロックで閉じるif out_file is not None: out_file.close()

備考:このコードは行数にのみ分割されています。これは、csvファイルに引用されたフィールドに改行が含まれている可能性があることを意味します...

+0

Ohh ..その場合は...新しい行を確認する必要があります。右? – user2597209

+0

@ user2597209:引用されたフィールドに改行を許可する場合は、csvリーダーで入力ファイルを解析し、csvライターで行を書き込むか、手動で解析する必要がありますが、 。 –

0

Pythonのマルチプロセッシングモジュールを使用することは間違いありません。

これは、1,000,000行のCSVファイルがある場合に達成した結果です。

import time 
from multiprocessing import Pool 

def saving_csv_normally(start): 
    out_file = open('out_normally/' + str(start/batch_size) + '.csv', 'w') 
    for i in range(start, start+batch_size): 
    out_file.write(arr[i]) 
    out_file.close() 

def saving_csv_multi(start): 
    out_file = open('out_multi/' + str(start/batch_size) + '.csv', 'w') 
    for i in range(start, start+batch_size): 
    out_file.write(arr[i]) 
    out_file.close() 

def saving_csv_multi_async(start): 
    out_file = open('out_multi_async/' + str(start/batch_size) + '.csv', 'w') 
    for i in range(start, start+batch_size): 
    out_file.write(arr[i]) 
    out_file.close() 

with open('files/test.csv') as file: 
    arr = file.readlines() 

print "length of file : ", len(arr) 

batch_size = 100 #split in number of rows 

start = time.time() 
for i in range(0, len(arr), batch_size): 
    saving_csv_normally(i) 
print "time taken normally : ", time.time()-start 

#multiprocessing 
p = Pool() 
start = time.time() 
p.map(saving_csv_multi, range(0, len(arr), batch_size), chunksize=len(arr)/4) #chunksize you can define as much as you want 
print "time taken for multiprocessing : ", time.time()-start 

# it does the same thing aynchronically 
start = time.time() 
for i in p.imap_unordered(saving_csv_multi_async, range(0, len(arr), batch_size), chunksize=len(arr)/4): 
    continue 
print "time taken for multiprocessing async : ", time.time()-start 

出力はそれぞれにかかる時間を示しています。私はp.mapに渡された関数として3つの別々の機能を定義している

length of file : 1000000 
time taken normally : 0.733881950378 
time taken for multiprocessing : 0.508712053299 
time taken for multiprocessing async : 0.471592903137 

はパラメータを1つだけ持つことができると私は、3つの異なるフォルダ内のCSVファイルを格納していてそれで私は3つの機能を書いたのです。

関連する問題