使用python批量将匹配行附加到csv文件

Posted

技术标签:

【中文标题】使用python批量将匹配行附加到csv文件【英文标题】:Batch Appending matching rows to csv files using python 【发布时间】:2013-11-03 19:51:46 【问题描述】:

我有一组 csv 文件和另一个 csv 文件 GroundTruth2010_edited_copy.csv,其中包含我想附加到文件集行末尾的信息。这些文件包含描述地质样本的信息。对于所有文件,包括 GroundTruth2010_edited_copy.csv,每一行都有一个识别样本的“rockid”,该行的其余部分描述了样本的各种参数。我想将 GroundTruth2010_edited_copy.csv 中的相应信息附加到 csv 文件集。也就是说,如果行具有相同的“rockid”,我想将它们组合成新 csv 文件中的新行。因此,集合中的每个原始 csv 文件都有一个新的 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

控制台返回“True”,所以在我看来,我至少应该得到一个“Ok!”用于最后的迭代。谁能帮我找出问题所在?

此外,由于我的 if 语句永远不会正确,因此我附加“new_data”的方式也可能存在问题。

【问题讨论】:

【参考方案1】:

你只打开一次rocreader,所以当你稍后在循环中尝试使用它时,你只会第一次从中获取行——在循环的其余部分运行中,你正在读取 0行(当然没有匹配)。要反复阅读,请在每次需要使用时打开和关闭一次。

但不要从磁盘重新扫描 Ground Truth 文件(慢!)为每个其他 CSV 的 每一 行,您应该将其读入字典一次,以便查找ID 一步到位。

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`

【讨论】:

您出于什么原因建议使用字典而不是 for 循环?我尝试了两者,发现它们花费的时间大致相同(但是,我在执行字典方法时正在运行其他一些程序)。这应该预期吗?是风格问题还是编码难易程度问题?我只是好奇,不想说你的方法有任何错误。 如果 GroundTruth 有 1000 行并且您有 10 个 CSV 文件,每个 2000 行,您的代码会读取 GroundTruth 20,000 次(每个新行一次)并进行 20,000,000 次比较;我的代码读取它一次并进行 20,000 次查找。如果您没有发现任何差异,那么您的测试一定是太小了,或者您的测量结果不准确。或者您的代码可能仍在不必要地重新读取 GroundTruth? 我不明白除了进行 1000 次比较之外,查找还有什么作用。它怎么知道条目是否包含在字典中?查找是否会在找到所需内容时停止比较? 阅读 python 字典。它使用一种称为“散列”的复杂数据结构,基本上可以让它一步一步知道要查找的位置。

以上是关于使用python批量将匹配行附加到csv文件的主要内容,如果未能解决你的问题,请参考以下文章

将日期列添加到python中的附加输出csv文件

csv在python中写数组到文件,如何删除附加行[复制]

使用 pandas 将不同位置的行附加到现有的 csv 文件

在 Python 中将行从一个 CSV 附加到另一个

使用特定于列的重复过滤器在 Python 中将行附加到 CSV

如何将 CSV 文件批量加载到 Snowflake 中,并将文件名添加为列?