2016-04-03 65 views
1
import numpy 
import pandas as pd 
import math as m 
import os 
import datetime 
from time import gmtime, strftime 


final = "D:/Technical_Data/final.csv" 

group_col_indx = 0 
group_col = pd.read_csv(final, usecols=[group_col_indx]) 
keys = group_col.iloc[:,0].unique() 

for key in keys: 
    df_list = [] 
    print key 
    reader = pd.read_csv(final, chunksize=20000) 
    for chunk in reader: 
     good_rows = chunk[chunk.iloc[:,group_col_indx] == key] 
     df_list.append(good_rows) 
    df_key = pd.concat(df_list) 
    file_save = "D:/Technical_Data_by_Date/" + str(key) + ".csv" 
    df_key.to_csv(file_save, header=False,index=False) 

在堆棧溢出和谷歌的幫助下,我想出了使用第一列將大文件分割成多個文件的代碼。 我在我的機器上運行它有8 GB的RAM。該程序運行速度非常慢。我如何加快速度?我做了2天的研究,這是我想出的腳本如何加快第一列上分割文件的代碼

+0

您預計會有多少個輸出文件?將它們全部打開是否合理? – tdelaney

+0

@tdelaney輸出文件的數量在600左右,將來會達到3000. – nnnnmmm

+0

正在使用groupby over iterator更好的想法嗎? – nnnnmmm

回答

2

儘管我做愛大熊貓,我不會在這種情況下使用它,因爲您似乎不想處理您的數據,只是將其分開。所以,如果你只是想通過鍵(日期),爲了將您的CSV文件,你可以簡單地使用gawk爲:

假設你的關鍵是在第二列$2(其他城市$2 - >$1如果您的鍵列在第一列)...

prg.awk

{ 
    key = $2 
    print > "D:/Technical_Data_by_Date/"key".csv" 
} 

命令:

gawk -F"," -f prg.awk final.csv 

它將工作更快

如果您通過各種手段想使用Python +熊貓 - 確保你讀你的輸入CSV文件那些(目前爲你做number of keys + 1倍,即約。 601次):

import pandas as pd 

fn = 'D:/Technical_Data/final.csv' 
sep=',' 
out_path = 'D:/Technical_Data_by_Date' 
chunk_size = 20000 
key_col_idx = 0 

reader = pd.read_csv(fn, sep=sep, chunksize=chunk_size) 

for chunk in reader: 
    # loop through keys 
    for key in chunk.iloc[:, key_col_idx].unique(): 
     # writing (appending: mode='a') data to CSV files (by key) 
     chunk[chunk.iloc[:, key_col_idx] == key] \ 
      .to_csv('{0}/{1}.csv'.format(out_path, key), 
        mode='a', header=None, index=False) 

PS的訣竅是使用mode='a'參數調用.to_csv()方法,該方法將附加數據到CSV文件,而不是覆蓋它

PPS它將被較慢相比AWK溶液時

0

我不知道這是否會更快,但由於您有太多的輸出文件一次保持打開,您可以打開文件在團隊中。這將減少您需要掃描輸入文件的次數。在這裏,我只是逐行進行讀取,並執行多個倒帶​​讀寫週期。如果您的csv很簡單,您可以加快速度,允許第一個逗號的簡單split找到密鑰,而不是使用龐大的csv模塊。

如果不是更快......至少有一個數據點告訴你pandas遊戲是否值得。

import os 
import csv 

final = "D:/Technical_Data/final.csv" 
outdir = "D:/Technical_Data_by_Date" 
maxfiles = 128 

with open(final) as infile: 
    reader = csv.reader(infile, buffering=32*1024*1024) 

    # scan file for keys 
    keys = list(set(row[0] for row in reader)) 

    # scan and write 'maxfiles' at a time 
    for keyidx in range(0, len(keys), maxfiles): 
     keygrp = keys[keyidx:keyidx+maxfiles] 
     outcsvs = {} 
     outfps = [] 
     try: 
      # open next group of output files 
      for key in keygrp: 
       fp = open(os.path.join(outdir, "{}.csv".format(key)), 
        "w", newline='', buffering=1024*1024) 
       outcsvs[key] = csv.writer(fp) 
       outfps.append(fp)    
      # rewind input and extract rows 
      infile.seek(0) 
      for row in reader: 
       writer = outcsvs.get(row[0]) 
       if writer: 
        writer.writerow(row) 
     finally: 
      for fp in outfps: 
       fp.close()