2012-02-28 132 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