2012-02-28 43 views
2

我有两个CSV文件(三列),我需要比较和提取匹配的其他文件(五列)的行。对于文件的例子是:比较从CSV文件的列中的条目,并提取匹配 - python

文件1:

ATGCGCGACAGT, ch3, 123546 
ATGCATACAGGATAT, ch2, 5141561615 

......等约100项

文件2:

ATGCGGCGACAGT,ch3, 123456,mi141515, AUCAGCUAUAUAU, UACGCAGAUAUAUA 
ATCAGACGATTATGA, ch4, 4564764, mi653453, AUCAGCAAUUUUCG, AUACAGACAAAAA 

....等约50000条目

我需要匹配列1,2和3的两个文件这样一种方式,所有三列file1应该与file2匹配。如果发生这种情况,请提取4,5和6列以供进一步处理。

我在想:

fhout=csv.writer(open('parsed_out', 'w'), delimiter=',') 

for i in file1: 

    a=[0] 
    b=[1] 
    c=[2] 
     for x in file2: 
     d=[0] 
     e=[1] 
     f=[2] 
     g=[3] 
     h=[4] 
     i=[5] 
     if a==d and b==e and c==f: 
      fhout.writerow([g]+[h]+[i]) 
     else: 
      pass 

但有人告诉我,我可以使用散列或一些更好的方式文件1

而写作10000多个条目这样的大循环请建议我更好的办法为了达成这个。文件1和文件2都是从更复杂的文件中解析出来的。

+1

你可以尝试将数据加载到一些sqlite表中,然后将它们加入你想要的列。 – imm 2012-02-28 03:23:56

回答

3

尝试类似:

import csv 

file_1_tuples = [] 

with open("file_1.csv") as fh: 
    csv_reader = csv.reader (fh) 
    for row in csv_reader: 
     file_1_tuples.append( tuple(row) ) 

with open("file_2.csv") as fh: 
    csv_reader = csv.reader (fh) 
    for row in csv_reader: 
     if tuple(row[0:3]) in file_1_tuples: 
      print (row[3:6]) 

当数据如下运行:

file_1.csv

person, john, smith 
person, anne, frank 
person, bob, macdonald 
fruit, orange, banana 
fruit, strawberry, fields 
fruit, ringring, banana 

file_2.csv

person, john, smith, 1, 2, 3 
person, anne, frank, 4, 5, 6 
person, bob, macdonald, 7, 8, 9 

它产生的输出

[' 1', ' 2', ' 3'] 
[' 4', ' 5', ' 6'] 
[' 7', ' 8', ' 9'] 

编辑:使用稍微更好的执行集和列表理解:

import csv, pprint 

with open("file_1.csv") as fh: 
    csv_reader = csv.reader (fh) 
    file_1_tuples = { tuple(row) for row in csv_reader } 

with open("file_2.csv") as fh: 
    csv_reader = csv.reader (fh) 
    matched_rows = [ row for row in csv_reader if (tuple(row[:3]) in file_1_tuples)] 

pprint.pprint (matched_rows) 

编辑2:注意,此实施方式是空格敏感在CSV文件中。如果CSV文件中的间距不一致,请使用类似row = [element.strip(' ') for element in row]的东西去除所有空格。

+0

为什么在file2中一个元组是由0-3构成的,与file_1_tuples匹配?它不应该是0-2吗?这是文件2的前三个元素与来自file1的元组相匹配。 – Bade 2012-03-01 01:03:28

+0

@AtulKakrana:在Python中对数组进行切片时,包含了起始索引,但是* end索引不是。*即对于'a = [10,20,30,40,50,60]','a [0:2 ]'只给出'[10,20]'。 'a [0:3]'或'a [:3]'会给出前三个元素'[10,20,30]'。 – 2012-03-01 01:09:21

2

将文件1中的字段放入一个元组中,然后将每个元组添加到一个集合中。然后,您可以对该组中的文件2中的前三个字段执行包容性测试,这比您的假设实施快得多。读第二个文件的查找速度更快时

S = {tuple(line) for line in csv.reader(File1)} 

然后:

+0

@Abrahms:谢谢你的帮助。你能否详细说明一下? File1:行中的所有三个字段构成一个元组。那之后我没有跟着。我的编程水平可以最好地描述为初学者。 – Bade 2012-02-28 03:38:37

+0

当你解析一行时,将采用'[a,b,c]'的形式,这是一个'list'。将它传递给'tuple'构造函数会将它变成一个'tuple'。 'sometuple =元组(somelist)' – 2012-02-28 03:40:26

+0

查看我对@ IgnacioVazquez-Abrams想法实现的回答。 (使用一个列表,而不是可能更有效的集合,但你明白了。) – 2012-02-28 03:54:47

3

下面创建使用一套修真的第一个文件,你建议的哈希值。

for line in csv.reader(File2): 
    key = tuple(line[:3]) 
    if key in S: 
     print(line) 
+1

集合理解+1,如老板。 – 2012-02-28 03:56:08

相关问题