2015-10-07 83 views
0

我正在处理两个大文件;大约每行100K行,我想在csv文件#2中搜索csv文件#1,然后根据匹配条件将csv文件#1中的另一个字符串连接到csv文件#2中的行。以下是我正在使用的数据和预期输出的示例:将CSV行与来自第二个CSV文件的字符串匹配合并

文件#1:要在文件#2中匹配的字符串是第2个元素; 1st将被附加到文件#2中的每个匹配行。 (整数要追加是粗体;串要被匹配为斜体为清楚起见只)

行1:

mta0000cadd503c.mta.net

第2排:

mta0000CADD5638.MTA.NET

行3:

mta00069234e9a51.DT.COM

文件#2:

第1行:

4246,211-015617,mta0000cadd503c.mta.net,老,NW MG2,BBand2 ESA,主动

行2:

7251,帐户mta0000CADD5638 .MTA.NET,FQDN,NW MG2,BBand2 ESA,主动

行3:

536887946,874-22558501,mta00069234e9a51.DT.COM, “P”,NW MG2,BBand2 ESA,主动

所需的输出从文件#1到整行接合粗体整数字符串在文件#2基于字符串匹配文件#1和文件#2之间:

行1:

4246,211-015617,mta0000cadd503c.mta。净,老,NW MG2,BBand2 ESA,活动,

行2:

7251,帐户mta0000CADD5638.MTA.NET,FQDN,NW MG2,BBand2 ESA ,活动,

行3:

536887946,874-22558501,mta00069234e9a51.DT.COM, “P”,NW MG2,BBand2 ESA,活动,

有许多情况下,在匹配字符串的情况下文件#1与文件#2的情况不匹配,但是字符匹配,因此对于匹配标准,情况可以被忽略。字符大小写在附加了文件#1中的整数字符串后,需要保存在文件#2中。

我是一个python newb,我已经在这里呆了一段时间,并在SE中搜索帖子,但似乎无法提供工作代码,使我可以直接打印出来文件#2中的一行与文件#1中的字符串匹配。我已经尝试了其他一些方法,比如写字典,使用Dictreader等,但还没有能够清除那些在这些方法中看起来很简单的错误,所以我试图将它解开为简单的列表,到达可以使用列表理解来合并数据的地步,然后将其写回到名为output的文件中,最终将该文件写回到csv文件。任何帮助或建议将不胜感激。运行此之后

import csv 

sg = [] 
fqdn = [] 
output = [] 
with open(r'file2.csv', 'rb') as src: 
    read = csv.reader(src, delimiter=',') 
    for row in read: 
     sg.append(row) 

with open(r'file1.csv', 'rb') as src1: 
    read1 = csv.reader(src1, delimiter=',') 
    for row in read1: 
     fqdn.append(row) 


output = output.append([s[0] for s in sg if fqdn[1] in sg]) 

print output  

结果是:

进程退出代码为0

+0

output.append修改原地输出并返回None。你也应该使用'.extend()'而不是'.append()'。 'append'将一个项目追加到列表中,而'extend'追加列表中的所有项目或迭代到列表中。而且在大多数情况下,更容易从for循环开始,而不是理解,因为在理解中,你倾向于过多地排成一行,这很快就会令人困惑,尤其是如果你对语言不熟悉的话。查看我的答案,找到一个简单的for-loop解决方案。 – cg909

回答

0

您应该使用字典文件#1不仅仅是一个列表完成,因为匹配更容易。只需将fqdn转换为字典,并在循环读取文件#1中设置字典中的键值对。我会在匹配键上使用.lower()。这转动钥匙为小写,所以你以后只需要检查是否在文件#2场的小写版本是在字典中键:

import csv 

sg = [] 
fqdn = {} 
output = [] 
with open(r'file2.csv', 'rb') as src: 
    read = csv.reader(src, delimiter=',') 
    for dataset in read: 
     sg.append(dataset) 

with open(r'file1.csv', 'rb') as src1: 
    read1 = csv.reader(src1, delimiter=',') 
    for to_append, to_match in read1: 
     fqdn[to_match.lower()] = to_append 

for dataset in sg: 
    to_append = fqdn.get(dataset[2].lower()) # If the key matched, to_append now contains the string to append, else it becomes None 
    if to_append: 
     dataset.append(to_append) # Append the field 
     output.append(dataset) # Append the row to the result list 

print(output) 

然后可以使用csv.writer创建CSV文件从结果。

+0

这真的很好......超快。谢谢!! – erns

0

下面是一个蛮力的解决方案来解决这个问题。对于第一个文件的每一行,您将搜索第二个文件的每一行,直到找到匹配。匹配的行将以您使用csv writer指定的格式写入output.csv文件。

import csv 

with open('file1.csv', 'r') as file1: 
    with open('file2.csv', 'r') as file2: 
     with open('output.csv', 'w') as outfile: 
      writer = csv.writer(outfile) 
      reader1 = csv.reader(file1) 
      reader2 = csv.reader(file2) 

      for row in reader1: 
       if not row: 
        continue 

       for other_row in reader2: 
        if not other_row: 
         continue 

        # if we found a match, let's write it to the csv file with the id appended 
        if row[1].lower() == other_row[2].lower(): 
         new_row = other_row 
         new_row.append(row[0]) 
         writer.writerow(new_row) 
         continue 

       # reset file pointer to beginning of file 
       file2.seek(0) 

在写出文件之前,您可能会试图将信息存储在数据结构中。根据我的经验,您总是会在将来获得更大的文件,并可能遇到内存问题。为了避免这个问题,我喜欢在找到匹配的文件时将其写入文件。

+0

似乎可以在我的小测试文件中工作,但是我的结果输出文件在每个条目之间都有空行。我将如何修改您的代码以删除这些空白行。我可以简单地添加一个sort()或类似的东西来消除它们吗?另外,我使用python 2.7,所以我认为我应该打开“wb”的csv文件,对吗? – erns

+0

我想知道在文件1的第二个字段中是否有换行符?我不会建议使用排序来解决这个问题。尝试在写出文件之前实际删除多余的换行符。 writerow方法会自动添加必要的换行符,所以你必须有一个来自某处的额外的换行符。 – djsosofresh

+0

找到了它......所以我只是试着在全尺寸的文件上运行它,其中file1约为1.5M,file2是9.7M,运行速度非常慢......我在10分钟后停下来检查它,输出看起来正确那很好。我能做些什么来加速它?我在OK硬件上运行它 - intel i7 w/16G Ram ...没有任何东西在后台运行。 – erns

相关问题