2013-10-24 88 views
1

我有一组csv文件和另一个csv文件GroundTruth2010_edited_copy.csv,它包含我想要追加到文件集行的末尾的信息。这些文件包含描述地质样本的信息。对于包括GroundTruth2010_edited_copy.csv在内的所有文件,每行都有一个识别样本的标识“rockid”,行的其余部分描述样本的各种参数。我想从GroundTruth2010_edited_copy.csv追加相应的信息到csv文件集。也就是说,如果行具有相同的“rockid”,我想将它们合并到新的csv文件中的新行中。因此,Set中的每个原始csv文件都有一个新的csv文件。这是我的代码。批量使用python将匹配行添加到csv文件

import os 
import csv 
#read in ground truth data 
csvfilename='GroundTruth/GroundTruth2010_edited_copy.csv' 
with open(csvfilename) as csvfile: 
    rocreader=csv.reader(csvfile) 
    path=os.getcwd() 
    filenames = os.listdir(path) 
    for filename in filenames: 
     if filename.endswith('.csv'): 
      #read csv files     
      r=csv.reader(open(filename)) 
      new_data = [] 
      for row in r: 
       rockid=row[-1] 

       for krow in rocreader: 
        entry=krow[0] 
        newentry=entry[:5] +entry[6:] #remove extra '0' from middle of entry 

        if newentry==rockid: 
         print('Ok!') 
         #append ground truth data 
         new_data.append([row, krow[1], krow[2], krow[3], krow[4]]) 

      #write csv files   
      newfilename = "".join(filename.split(".csv")) + "_GT.csv" 
      with open(newfilename, "w") as f: 
       writer = csv.writer(f) 
       writer.writerows(new_data) 

代码运行,使我的新的CSV文件,但它们都是空的。问题似乎是我的第二个'if'陈述从来都不是真的:控制台从不打印'Ok!'我尝试了一下故障排除,并且感到很沮丧。也许最令人沮丧的是,之后的程序完成,如果我进入

rockid==newentry 

控制台返回“真”,所以在我看来,我应该得到至少一个“好!”进行最后的迭代。任何人都可以帮我找到有什么问题吗?

此外,由于我的if语句从不是真的,所以我追加'new_data'的方式可能也有问题。

回答

2

您只需打开rocreader一次,因此当您稍后尝试在循环中使用它时,第一次只通过循环的其余部分获取行 - 在循环的其余部分中,您正在读取0行(当然没有匹配)。要反复阅读,每次需要使用时打开并关闭一次。

但不是重新扫描磁盘地面实况文件(慢!)为行其他每个CSV中的,你应该读它一旦进入一个字典,所以你可以看一下标识一步到位。

with open(csvfilename) as csvfile: 
    rocreader=csv.reader(csvfile) 
    rocindex = dict((row[-1], row) for row in rocreader) 

则对任意键newentry,你可以检查这样的:

if newentry in rocindex: 
    truth = rocindex[newentry] 
    # Merge it with the row that has key `newentry` 
+0

是什么原因,你劝使用字典而不是for循环?我尝试了两种方法,发现他们花费的时间相同(不过,我在执行字典方法时正在运行一些其他程序)。这应该是预期的吗?这是一种风格还是易于编码的问题?我只是好奇,并不是想说你的方法在任何方面都是错误的。 – PatEugene

+0

如果GroundTruth有1000行,并且每行有2000行的10个CSV文件,则您的代码将读取GroundTruth 20,000次(每个新行一次)并进行20,000,000次比较;我的代码读取一次,并进行20,000次查找。如果你看不出有什么不同,你的测试一定是太小了,或者你的测量不准确。或者你的代码仍然不必要地重读GroundTruth? – alexis

+0

我不明白的是,除了进行1000次比较之外,查找还做了些什么。如果条目包含在字典中,还能知道其他什么?当查找发现它正在查找的内容时,查找是否会停止比较? – PatEugene