0

私はPythonを初めて使用し、2つのタブ区切りの入力ファイルに対して2つの配列を作成しました.1つの配列の列(要素)を数値的に別の配列の要素と比較する方法を探していました。それを行う方法はありますか.今までの私のコードは以下のとおりです

#!/usr/bin/python
import sys
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 ("12877overlappedallvariants.gvf", "r")
f2 = open ("unmatched.12877overlappedallvariants.gvf", "r")
f3 = open ("out.txt", "w")

for line in f1.readlines():
 cols = line.split('\t')
 #print cols[5:6]


for line in f2.readlines():
 cols1 = line.split('\t')
 #print cols1[5:6]

コードのセクションの下でこれを試しましたが、機能しません

slice1 = cols[5:6]
slice2 = cols1[5:6]
new_list = []
for element in slice1:
 if element in slice2:
  new_list.append(element)
  print new_list  

array1 の要素 5 が array2 の要素 5 と等しいか、それよりも大きいか小さいかを確認しようとしています。どんな助けでも大歓迎です。ありがとう。

4

3 に答える 3

1

これらは配列ではなくリストであることに注意してください。違いがあります。

colsループするたびに上書きしています-つまり、データの最後の行のみを取得します-リスト内包表記は、必要なすべてのデータを取得するためのものです。または、さらに良いことに、データをまったく保存しないでください-実行しますその上で必要な操作。

比較の主な問題は、必要な要素を取得するだけでなく、リストのスライスを取得していることです。これは、あなたがやろうとしていることを過度に複雑にしています。

withそのため、コメントで述べたように、最初のコード (主にステートメントとcsvモジュール) に多くの改善を加えることができます。

まず、withステートメントを使用してファイルを開きます。csv.reader()同様に、"excel-tab"方言をタブ区切りファイルとして使用csv.QUOTE_NONNUMERICし、値が数値であることを伝えるために、後で文字列から変換する必要がないようにします。特定の値のみが数値である場合、このメソッドを使用するには数値以外の値をすべて引用符で囲むか、それらの値を明示的に変換して使用しないようにする必要があります。

with open("file1.tsv") as file1, open("file2.tsv") as file2:
    rows = csv.reader(file2, dialect="excel-tab", quoting=csv.QUOTE_NONNUMERIC)
    rows1 = csv.reader(file2, dialect="excel-tab", quoting=csv.QUOTE_NONNUMERIC)

チェックを実行するには、次のようにします (with上記のブロック内から続きます)。

    for cols, cols1 in zip(rows, rows1): #Use itertools.izip() in 2.x for efficiency.
        first = cols[4]
        second = cols1[4]

        if first < second:
            ...
        elif first == second:
            ...
        else: #first > second
            ...

zip を使用して両方のファイルを一度にループすることに注意してください。ファイルが一度に 1 行ずつ返すときに、ファイルをループする必要があります。各行は、各列のデータのリストです。その後、データを好きなように処理できます。5 番目の値を比較する例を示しました (インデックスに注意してください4- python には0インデックスが付けられています - つまり、最初の値は0であるため、5 番目の値は です4)。

ファイルをループしながらこれをすべて行うことで、リストを作成してデータを一時的に保存する必要がなくなります。これは、大きなファイルで作業する場合に便利です。

そのデータを後で何度も使用する必要があり、それをリストとして使用したい場合は、rowss .list()csv.reader()

于 2012-06-20T13:44:57.360 に答える
0

知っておく必要があることがいくつかあります。まず、ファイルを読み取った後、最後の行しか保存されていません (「cols」という変数に格納されています)。次のようなループ:

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

for f1line,f2line in zip(lines1,lines2):
    #compare here

おそらくより適切です。これにより、両方のファイルの内容全体がメモリに読み込まれます。一度に大量のデータを読み込まずにこれを行う方法は確かにありますが、これが最も簡単な場合もあります。 zip少し紛らわしいかもしれませんが、基本的には、file1 の最初の行を file2 の最初の行と一致させ、次に両方のファイルの 2 行目を一致させる、というように...

@Lattyware のコメントに記載されているように、上記は次と同等です。

for f1line,f2line in zip(f1,f2):
    #compare here

ファイルは反復できるためです。Python 2では、両方のファイルを一度に読み取り/保存しますが、Python 3では、一度にそれぞれから1行しか生成しません。最後に、ファイルのすべての内容を python 2 に保存したくない場合は、次を使用できます。itertools.izip

import itertools
for f1line,f2line in itertools.izip(f1,f2):
    #compare here    

zipこれは、一度に 1 つの要素を生成することを除いて、同じように機能します。ここでの欠点は、itertools.izippython 3 に移行するとなくなることです...ただし、この場合2to3は適切な変換を行う必要があります。(詳細については、コメントを参照してください)。

比較に関しては、ファイルの内容に大きく依存します。数字が含まれている場合は、次のようにすることができます...

 for f1line,f2line in zip(lines1,lines2):
     row1=map(float,f1line.split())
     row2=map(float,f2line.split())
     #compare the 5th element
     if(row1[4]==row2[4]):
         #equal
     elif(row1[4]>row2[4]):
         ... 

ビットがない場合map(float,...)、python は文字列比較を行います。

python にはcmp 関数もあり、今比較して後で比較結果を使用する場合に便利です。

于 2012-06-20T13:50:42.410 に答える
0

私はそれを次のように書きます:

import csv

file1 = csv.reader(open('name1'), delimiter='\t')
file2 = csv.reader(open('name2'), delimiter='\t')

for row1, row2 in zip(file1, file2):
    print cmp(row1[5], row2[5])

`

cmp は、lt の場合は -1、eq の場合は 0、gt の場合は 1 を返します。

行?[5] が数値の場合...

print cmp(float(row1[5]), float(row2[5])) # or int, or any other dtype
于 2012-06-20T13:50:45.577 に答える