2012-11-30 4 views
0

일부 데이터 파일을 처리하기위한 스크립트를 작성하고 싶습니다. 데이터 파일의 데이터 열 단지 ASCII 텍스트 있으며, 다음은 간단한 예이다 ...파이썬에서 코드 중복없이 데이터 파일을 반복 할 수 있습니까?

첫 번째 열은 1 내지 3 번째 열이 경우의 ID 번호, 관심있는 값이다. (실제 사용하는 파일에는 더 많은 ID와 값이 있지만 여기서 간단하게 유지합시다.)

data.txt로 내용 : I 데이터를 반복하고 각 ID의 값을 추출하고이를 처리, 즉 ID 1에 대한 모든 값을 가져 그들과 함께 무언가를 할

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 2에 대한 모든 값은 그래서 파이썬이를 작성할 수 있습니다.

#!/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() (각 새 ID마다 루프 내에 하나, 마지막 ID 루프에 하나씩)이라는 두 가지 함수 호출을 수행하지 않고이 작업을 수행 할 수 있습니까? 내가 생각할 수있는

수있는 유일한 방법은 행 번호를 저장하고 우리가 마지막 줄에 있다면 루프에 확인하는 것입니다. 하지만 인덱스 나 총 줄 수가 아니라 줄 자체를 저장하는 'foreach'스타일 처리의 요점을 제거하는 것 같습니다. 이것은 perl과 같은 다른 스크립팅 언어에도 적용됩니다. 여기에서는 while(<FILE>) 인 행을 반복하고 나머지 행 수를 모르는 경우가 많습니다. 마지막에 함수 호출을 다시 작성해야합니까?

답변

3

당신은 키의 모든 항목이 contigious 경우 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 

는 다른 방법 - 당신은 또한 기본값으로 listcollections.defaultdict를 사용하여 볼 수 있습니다. loadtxt()

1

는 다음과 같이 갈 수

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.]]