2013-10-31 31 views
2

所以,我希望Python使用csv读取器/写入器来获取目录中的所有CSV并将它们合并,同时过滤出包含第二列中的任何其他行的值。使用特定于列的复制过滤器将行附加到CSV

这里是我的unworking脚本:

import csv 
import glob 

with open('merged.csv','a') as out: 
    seen = set() 
    output = [] 
    out_writer = csv.writer(out) 
    csv_files = [f for f in glob.glob('*.csv') if 'merged' not in f] 
#csv_files = glob.glob('*.csv') 
    # I'd like to use all files including the output so that I don't 
    # have to rename it when reusing the script - it should dupe-filter itself! 
for filename in csv_files: 
    with open(filename, 'rb') as ifile: 
     read = csv.reader(ifile, delimiter=',') 
     for row in read: 
      if row[1] not in seen: 
       seen.add(row[1]) 
       if row: #was getting extra rows 
        output.append(row) 
out_writer.writerows(output) 

我觉得我必须缺少简单的东西。我的文件大小都是100MB左右,我最终希望自动执行此操作,以便不同的计算机可以共享一个合并文件进行复制检查。

要获得额外的功劳,我将如何更改此项以检查同时具有row[1]row[2]共同点的行? (一旦过滤器和自我包容工作,当然...)

回答

1

这不仅仅是熊猫可能需要的少量行数,因为它是股票Python,但另一方面它比较直接,会过滤多个列值,并处理重新读取以前的结果。它使用fileinput模块,允许它将多个输入文件视为单个连续的数据行流。

import csv 
import fileinput 
import glob 
import os 

merged_csv = 'merged.csv' 
columns = (1, 2) # columns used for filtering 
pathname = '*.csv' 
tmpext = os.extsep + "tmp" 
csv_files = glob.glob(pathname) 

if merged_csv not in csv_files: 
    prev_merged = None 
else: 
    prev_merged = merged_csv + tmpext 
    os.rename(merged_csv, prev_merged) 
    csv_files[csv_files.index(merged_csv)] = prev_merged 

with open(merged_csv, 'wb') as ofile: 
    csv_writer = csv.writer(ofile) 
    written = set() # unique combinations of column values written 
    csv_stream = fileinput.input(csv_files, mode='rb') 
    for row in csv.reader(csv_stream, delimiter=','): 
     combination = tuple(row[col] for col in columns) 
     if combination not in written: 
      csv_writer.writerow(row) 
      written.add(combination) 

if prev_merged: 
    os.unlink(prev_merged) # clean up 

print '{!r} file {}written'.format(merged_csv, 're' if prev_merged else '') 
2

我会建议使用熊猫而不是csv作家。我会重写你的代码是这样的:

import pandas as pd 
import glob 

data = pd.concat([pd.DataFrame.from_csv(file) for 
        file in glob.glob("*.csv")]).drop_duplicates(cols=COLNAME_LIST) 
data.to_csv('merged.csv') 

在充分披露我没有测试此代码,我没有躺在附近一吨的CSV文件,但我之前已经写了类似的事情成功

+1

哎呀,如果你觉得各种万圣节疯狂的,你甚至可以让一个班轮'pd.concat([pd.DataFrame.from_csv(文件)在glob.glob文件(” * .csv“)])。drop_duplicates(cols = COLNAME_LIST).to_csv('merged.csv')' –

+0

真棒 - 我一直在想着和熊猫一起工作,因为我其实有很多这种东西可以工作用。现在进入比等到必要并且必须翻译所有内容更有意义。这只会检查重复,如第2列,还是会丢弃任何在任何列条目上的欺骗?我真的需要查找关于熊猫的基础知识。 – Xodarap777

+0

您可以向其传递一列您想要检查上面(参见COLNAME_LIST)中的重复项的列。它有助于在列上添加标签(可以通过将文件中的第一行作为标题名称来完成),但如果不这样做,它们只会包含数字标题。你应该注意的另一件事是索引,因为它们被自动创建为每行中的第一个值。我不确定你的csv文件是如何构建的,但希望这对你来说不是问题。 –