0

あるタブ区切りファイルの列を格納する配列の 0,2,3,4 要素を、別のタブ区切りファイルの列を格納する別の配列の 0,2,3,4 要素と一致させ、要素を出力しようとしています。 Python の両方の入力ファイルから 5 (列 6)。

これが私が取り組んだコードですが、コードは2つのファイル間で1行ずつ一致していると思います。ただし、file1の行をfile 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])

編集:見つかった問題:

キー関数からの戻り値はリストでした。リストはハッシュ可能ではないため、辞書のキーにすることはできません。代わりに戻り値をタプルにしました。

一方、あなたはそれについて言及しませんでした

  • ファイルは数行のコメントで始まります (コメント行を無視するようにスクリプトを変更しました。つまり、 で始まるものを意味します##) 。

  • あなたのファイルはタブ区切りではありません(または少なくとも提供したファイルの例はそうではありません)。実際には、複数のスペースで区切られた円柱状のようです-これは 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 に答える