0

いくつかのデータファイルを処理するスクリプトを書きたいです。データファイルは、データの列を含むASCIIテキストです。簡単な例を次に示します...

最初の列はID番号で、この場合は1から3です。2番目の列は対象の値です。(私が使用している実際のファイルには、さらに多くのIDと値がありますが、ここでは単純にしましょう)。

data.txtの内容:

1 5
1 4
1 10
1 19
2 15
2 18
2 20
2 21
3 50
3 52
3 55
3 70

データを反復処理して各IDの値を抽出し、それらを処理します。つまり、ID 1のすべての値を取得し、それらを使用して何かを実行してから、ID2のすべての値を取得します。

だから私はこれをPythonで書くことができます。

#!/usr/bin/env python

def processValues(values):
  print "Will do something with data here: ", values

f = open('data.txt', 'r')
datalines = f.readlines()
f.close()

currentID = 0
first = True

for line in datalines:
    fields = line.split()

    # if we've moved onto a new ID,
    # then process the values we've collected so far
    if (fields[0] != currentID):

        # but if this is our first iteration, then
        # we just need to initialise our ID variable
        if (not first):
            processValues(values) # do something useful

        currentID = fields[0]
        values = []
        first = False

    values.append(fields[1])

processValues(values) # do something with the last values

私が抱えている問題はprocessValues()、最後にもう一度呼び出さなければならないということです。したがって、これにはコードの重複が必要であり、いつかこのようなスクリプトを記述してprocessValues()、最後に余分なものを入れるのを忘れて、最後のIDを見逃してしまう可能性があることを意味します。また、それが「最初の」反復であるかどうかを保存する必要があり、これは煩わしいことです。

processValues()とにかく、2つの関数呼び出し(新しいIDごとにループ内に1つ、最後のIDのループの後に1つ)を持たずにこれを行うことはできますか?

私が考えることができる唯一の方法は、行番号を保存し、最後の行にいるかどうかをループでチェックすることです。ただし、インデックスや行の総数ではなく、行自体を格納する「foreach」スタイルの処理のポイントが削除されているようです。これは、perlのような他のスクリプト言語にも当てはまります。この場合、行を繰り返し処理するのが一般的でwhile(<FILE>)あり、残りの行数がわかりません。最後に関数呼び出しを書き直す必要がありますか?

4

2 に答える 2

3

キーのすべての出現が連続している場合は、 itertools.groupbyを確認する必要があります-基本的な例...

from itertools import groupby
from operator import itemgetter

with open('somefile.txt') as fin:
    lines = ( line.split() for line in fin )
    for key, values in groupby(lines, itemgetter(0)):
        print 'Key', key, 'has values'
        for value in values:
            print value

または、デフォルトとしてaを指定してcollections.defaultdictを使用することもできlistます。

于 2012-11-30T12:25:11.443 に答える
1

それでloadtxt()このようになるかもしれません:

from numpy import loadtxt

data = loadtxt("data.txt")
ids = unique(data[:,0]).astype(int)

for id in ids:
    d = data[ data[:,0] == id ] 
    # d is a reduced (matrix) containing data for <id>
    # ....... 
    # do some stuff with d

あなたの例のprint dために与えるでしょう:

id= 1 
d=
[[  1.   5.]
 [  1.   4.]
 [  1.  10.]
 [  1.  19.]]
id= 2 
d=
[[  2.  15.]
 [  2.  18.]
 [  2.  20.]
 [  2.  21.]]
id= 3 
d=
[[  3.  50.]
 [  3.  52.]
 [  3.  55.]
 [  3.  70.]]
于 2012-11-30T12:36:54.457 に答える