2014-04-17 2 views
0

단일 파일의 데이터를 두 개의 개별 파일로 서브 세트하고 각 파일의 행을 개별적으로 계산하려고합니다.데이터를 부분 집합하고 각 파일의 행 수를 계산하십시오.

ID,MARK1,MARK2 
sire1,AA,BB 
dam2,AB,AA 
sire3,AB,- 
dam1,AA,BB 
IND4,BB,AB 
IND5,BB,AA 

하나 개의 파일은 다음과 같습니다

ID,MARK1,MARK2 
sire1,AA,BB 
dam2,AB,AA 
sire3,AB,- 
dam1,AA,BB 

가 다른 하나는 다음과 같습니다

import re 
def file_len(filename): 
    with open(filename, mode = 'r', buffering = 1) as f: 
     for i, line in enumerate(f): 
      pass 
    return i 

inputfile = open("test.txt", 'r') 
outputfile_f1 = open("f1.txt", 'w') 
outputfile_f2 = open("f2.txt", 'w') 

matchlines = inputfile.readlines() 
outputfile_f1.write(matchlines[0]) #add the header to the "f1.txt" 
for line in matchlines:  
    if re.match("sire*", line): 
     outputfile_f1.write(line) 
    elif re.match("dam*", line): 
     outputfile_f1.write(line) 
    else: 
     outputfile_f2.write(line) 
print 'the number of individuals in f1 is:', file_len(outputfile_f1) 
print 'the number of individuals in f2 is:', file_len(outputfile_f2) 
inputfile.close() 
outputfile_f1.close() 
outputfile_f2.close() 

코드는 파일을 서브 세트를 분리 할 수 ​​있습니다 :

다음
ID,MARK1,MARK2 
IND4,BB,AB 
IND5,BB,AA 

내 코드입니다 그냥 괜찮아요,하지만 난 특히 길을 좋아하지 않아요. 새 파일에 헤더를 추가합니다. 더 좋은 방법이 있는지 궁금합니다. 또한,이 함수는 줄을 계산 잘 보이는,하지만 난 그것을 실행했을 때, 그것은 그래서 난 여전히 해결되지, (원래 코드에서이 아니었다),이 사이트를 봤 buffering = 1을 추가

"Traceback (most recent call last): 
    File "./subset_individuals_based_on_ID.py", line 28, in <module> 
    print 'the number of individuals in f1 is:', file_len(outputfile_f1) 
    File "./subset_individuals_based_on_ID.py", line 7, in file_len 
    with open(filename, mode = 'r', buffering = 1) as f: 
TypeError: coercing to Unicode: need string or buffer, file found 
" 

나에게 오류를 준 문제.

코드를 개선하고 오류를 해결하는 데 도움을 주셔서 감사합니다.

답변

1

itertools.tee을 사용하여 입력을 여러 스트림으로 분할하고 개별적으로 처리 할 수도 있습니다.

import itertools 

def write_file(match, source, out_file): 
    count = -1 
    with open(out_file, 'w') as output: 
     for line in source: 
      if count < 0 or match(line): 
       output.write(line) 
       count += 1 

    print('Wrote {0} lines to {1}'.format(count, out_file)) 


with open('test.txt', 'r') as f: 
    first, second = itertools.tee(f.readlines()) 

    write_file(lambda x: not x.startswith('IND'), first, 'f1.txt') 
    write_file(lambda x: x.startswith('IND'), second, 'f2.txt') 

편집 - 제거 중복의 elif

+0

정말 고마워요. 정말 멋집니다! – user2489612

+1

똑같은 일을하는 두 가지 다른 조건이있는 이유는 무엇입니까? 그냥'또는'을 사용하십시오. –

+0

그건 당황 스럽네. 감사. – dmcauslan

1

난 당신을 오독 수 있습니다,하지만 난 그냥이 일을하려고하는 생각 :

ID,MARK1,MARK2 
sire1,AA,BB 
dam2,AB,AA 
sire3,AB,- 
dam1,AA,BB 
: 후 test_out1

ID,MARK1,MARK2 
sire1,AA,BB 
dam2,AB,AA 
sire3,AB,- 
dam1,AA,BB 
IND4,BB,AB 
IND5,BB,AA 

내용 : 전 test

>>> with open('test', 'r') as infile: 
... with open('test_out1', 'w') as out1, open('test_out2', 'w') as out2: 
...  header, *lines = infile.readlines() 
...  out1.write(header) 
...  out2.write(header) 
...  for line in lines: 
...  if line.startswith('sir') or line.startswith('dam'): 
...   out1.write(line) 
...  else: 
...   out2.write(line) 

내용

다음 내용은 test_out2입니다.

ID,MARK1,MARK2 
IND4,BB,AB 
IND5,BB,AA 
+0

는 "헤더, * 라인 =의 infile.readlines()"를 무엇을 조금 설명 할 수있는이 말은? – user2489612

+0

처음 몇 개의 값만 신경 쓰면 목록을 푸는 것이 좋습니다. 'a, b, c, * d = [0, 1, 2, 3, 4, 5]'는 0, b 1, c 2 및 d [3, 4, 5]를 만든다. –

관련 문제