2013-06-30 54 views
2

我有2000個文件,我想結合列表:結合CSV文件蟒套

01-0628-11A-01D-0356-01_hg19 
01-0628-11A-01D-0356-01_hg20 
01-0628-11A-01D-0356-01_hg21 
01-1372-11A-01D-0356-01_hg16 
01-1372-11A-01D-0356-01_hg17 
... 


我已經得到的文件到一個水珠,並使用正則表達式來重命名文件轉換爲通用標識符(下面顯示的六位數字代碼),但每個標識符的原始文件數量不盡相同。

01-0628 
01-0628 
01-0628 
01-1372 
01-1372 
... 

我本來打算只使用一個閱讀器和打開與通用名的每個文件,但我不知道是否有這樣做更有效的方式。

最終的輸出,我想是下面的,每個共同標識符文件合併成一個:

01-0628 
01-1372 
... 

所有的文件都包含類似格式化數據,因此只需將現有的文件apending到一個新的文件不會是一個問題。

+0

看起來你需要打開每個文件嗎?所以我看不出如何找到更有效的方法來做到這一點,而不是一個接一個地打開它們。 –

+0

你不能只讀通過每個文件並打開('newlargefile.csv','a')到一個新的大文件或第一個文件?它只會將新行添加到書面文件的底部。示例:http://stackoverflow.com/questions/4706499/how-do-you-append-to-file-in-python –

回答

1

假設這些csvs具有相似或相同的字段。此代碼應該可以工作。它使用將csv行轉換爲Python字典的csv模塊的DictReader和DictWriter類。

1)它打開並從in_csv_dir中讀入globbed csv文件到(filename,rows)字典中。

2)它根據文件名和prefix_length變量將csv行分組成一個(前綴,行)字典。

3)它組合每個前綴分組的字段並在out_csv_dir中創建一個組合的csv。

4)由於字典鍵是無序的,您的csvs可能會有特定的字段順序。這可以輸入到field_order中。這將對csv字段進行排序,但不會在field_order中未定義的字段上失敗。

import os 
import sys 

# Import System libraries 
from csv import DictReader, DictWriter 
import glob 

in_csv_dir = ".\\csvs" 
out_csv_dir = ".\\combined_csvs" 
prefix_length = 2 

field_order = ["NAME", "TITLE", "COMPANY", "LOCATION"] 
field_check = lambda q: field_order.index(q) if(field_order.count(q)) else sys.maxint 
csvs = {} 
gotten_files = glob.glob(os.path.join(in_csv_dir, "*.csv")) 
for glob_filename in gotten_files: 
    print "%-11s%s" % ("Opening:", glob_filename) 
    file_obj = open(glob_filename, "rb") 
    cur_reader = DictReader(file_obj) 
    cur_record = [q for q in cur_reader.__iter__()] 
    file_obj.close() 
    if(cur_record): 
     (path, filename_ext) = os.path.split(glob_filename) 
     (filename, ext) = os.path.splitext(filename_ext) 
     csvs[filename] = cur_record 

csv_prefixes = list(set([x[:prefix_length] for x in csvs.keys()])) 
csv_groups = dict([(prefix, []) for prefix in csv_prefixes]) 
map(lambda (key, value): csv_groups[key[:prefix_length]].extend(value), csvs.items()) 

for (key, sub_csvs) in csv_groups.items(): 
    com_keys = list(reduce(lambda x, y: x|set(y.keys()), sub_csvs, set([]))) 
    com_keys.sort(cmp=lambda x, y: field_check(x) - field_check(y)) 

    filename = os.path.join(out_csv_dir, "%s.csv" % key) 
    print "%-11s%s" % ("Combining:", filename) 
    file_obj = open(filename, "wb") 
    temp_csv = DictWriter(file_obj, com_keys) 

    temp_csv.writerow(dict(zip(com_keys, com_keys))) 
    map(lambda x: temp_csv.writerow(x), sub_csvs) 
    file_obj.close()