0

我正在尝试将存储一个制表符分隔文件的列的数组的 0,2,3,4 元素与存储另一个制表符分隔文件的列的另一个数组的 0,2,3,4 元素匹配并打印出该元素来自python中的两个输入文件的5(第6列)。

这是我处理的代码,但我猜代码在两个文件之间逐行匹配。但是,我想将 file1 的行与文件 2 中的任何行匹配

#!/usr/bin/python
import sys
import itertools
import csv, pprint
from array import *
#print len(sys.argv)
if len(sys.argv) != 4:
print 'Usage: python scores.py <infile1> <infile2> <outfile>'
sys.exit(1)

f1=open("/home/user/ab/ab/ab/file1.txt", "r")
f2 = open ("/home/user/ab/ab/ab/file2.txt", "r")
f3 = open ("out.txt", "w")

lines1 = f1.readlines()
lines2 = f2.readlines()

for f1line, f2line in zip(lines1, lines2): ## for loop to read lines line by line simultaneously from two files
    #for f1line, f2line in itertools.izip(lines1,lines2):
    row1 = f1line.split('\t') #split on tab
    row2 = f2line.split('\t') # split on tab

    if ((row1[0:1] + row1[2:5]) == (row2[0:1] + row2[2:5])): # columns 0,2,3,4 matching between two infiles 
        writer = csv.writer(f3, delimiter = '\t')
        writer.writerow((row1[0:1] + row1[2:5]) + row1[5:6] + (row2[0:1] + row2[2:5]) + row2[5:6])
4

3 回答 3

2

对于文件 1 上要匹配的每一行

op = operator.itemgetter(0,2,3,4)
f2 = file2.readlines() # otherwise it won't work every loop

for line1 in file1:
    ... #split 1
    for line2 in f2:
        ... #split 2
        if op(row1) == op(row2):
            ...
于 2012-07-03T16:35:44.950 回答
1

所以,就照你说的做:对于file1的每一行,匹配file2的每一行

for f1line in lines1:
    row1 = f1line.split('\t') #split on tab
    for f2line in lines2:
        row2 = f2line.split('\t') # split on tab
        if ((row1[0:1] + row1[2:5]) == (row2[0:1] + row2[2:5])):
            ...
于 2012-07-03T16:34:59.987 回答
0

这假设每个键值(行 [0,3,4,5])对于每个文件都是唯一的:

import sys
import csv

datalen = 12
keyfn  = lambda row: tuple(row[0:1] + row[3:6])
datafn = lambda row: row[8:datalen]

def load_dict(fname, keyfn, datafn):
    with open(fname, 'rb') as inf:
        data = (row.split() for row in inf if not row.startswith('##'))
        return {keyfn(row):datafn(row) for row in data if len(row) >= datalen}

def main(fname1, fname2, outfname):
    data1 = load_dict(fname1, keyfn, datafn)
    data2 = load_dict(fname2, keyfn, datafn)

    common_keys = sorted(set(data1).intersection(data2))
    with open(outfname, 'wb') as outf:
        outcsv = csv.writer(outf, delimiter='\t')
        outcsv.writerows(list(key) + data1[key] + data2[key] for key in common_keys)

if __name__=="__main__":
    if len(sys.argv) != 4:
        print 'Usage: python scores.py <infile1> <infile2> <outfile>'
        sys.exit(1)
    else:
        main(*sys.argv[1:4])

编辑:发现问题:

我犯了一个错误:key 函数的返回值是一个列表;列表不可散列,因此不能是字典键。我已将返回值设为元组。

另一方面,你没有提到

  • 您的文件以几行注释开头(我已修改脚本以忽略注释行,这意味着任何以 开头的内容##

  • 您的文件不是制表符分隔的(或者至少您提供的文件示例不是)。它实际上似乎是柱状的,用多个空格分隔 - 这不能由 csv 模块处理。幸运的是,数据看起来很简单,可以使用 .split() 代替。

  • 您在错误的列上匹配;数据文件中的第 2 列似乎在文件之间根本不匹配。我认为您需要改为键入第 0、3、4、5 列。我已经更新了 keyfn 以反映这一点。

第 3 列和第 4 列似乎相同,但我不确定这一点。如果第 3 列和第 4 列始终相同,则只需键入第 0、4、5 列即可节省一些内存并加快速度:keyfn = lambda row: tuple(row[0:1] + row[4:6])

我猜第 8、9、10、11 列是所需的数据;我已更改 datafn 以反映这一点。该脚本现在应该可以按要求工作了。

于 2012-07-03T17:01:47.610 回答