2013-07-09 2 views
0

I는 다음과 같은 두 개의 별도의 파일에서 텍스트를 취하려합니다 :파이썬 텍스트 파일 조작

File 1: 
000892834  13.663  0.098  0.871  0.093  0.745  4.611  4795 

File 2: 
892834 4916 75 37 4857 130 128 4795 4.61 -0.09 0 0 

및 출력과 같은 얻을 : 나는 몇 가지 코드가

892834  13.663  0.098  0.871  0.093  0.745  4.611  4795 
892834  4916  4795  -0.09 

을 그 해결책에 가까운 것 같습니다 :

filter_func_1 = lambda x: x >= 15 
filter_func_2 = lambda x: (5777 + 100) > x > (5777 - 100) 
mergedData = defaultdict(list) 
with open('Table1_Karoff.txt') as file_1, open('Table7_Pinsonneault.txt') as file_2, open('Processed_Data.txt', 'w') as outfile: 
     for line_1 in file_1: 
      splt_file_1 = line_1.split() 
      if filter_func_1(splt_file_1[1]): 
       mergedData[splt_file_1[0].lstrip('0')].append(line_1) 
     for line_2 in file_2: 
       splt_file_2 = line_2.split() 
     Data = map(itemgetter(0, 1, 8, 9), line_2) 
      if filter_func_2(splt_file_2[1]): 
       mergedData[splt_file_2[0]].append([' '.join(map(str, i)) for i in Data]) 
     for k in mergedData: 
      if len(mergedData[k]) == 2: 
       outfile.write("\n".join(mergedData[k]) + "\n")   
     return outfile 

이 코드는 '해야 할 일'이 두 종류의 필터를 만듭니다. 각 람다의 특정 인덱스를 람다 함수와 비교하여 그것이 맞는지 확인하고, 일치하는 경우 전체 행을 출력 목록에 추가하십시오. 또한 파일 1의 첫 번째 숫자의 시작 부분에서 '000'을 제거하고 동일한 첫 번째 숫자가 두 파일에 모두 존재하는지 확인합니다.

내 문제는 다음과 같습니다 file_1의 ID 번호 (즉, 첫 번째 숫자는) 제대로 내 지식에 코드가 그 일을해야하더라도, 0의 그것에서 제거 모든이없는

1). 00892834로 출력하므로 첫 번째 0 만 제거합니다.

2) 필터를 추가 한 후에는 새 파일에 전혀 데이터가 기록되지 않고 line.split이 제대로 만들어 졌는지 확인했을 때 새로운 목록인데, splt_file_ # 입력에 데이터가 없으므로 필터링 할 데이터가 없다는 것을 의미합니다. 이것은 나에게 이상하고 나는 그것이 어떻게 일어날 수 있는지 이해하지 못한다. 필자는 목록 작성을 위해 최종적으로 splt_file_1 및 splt_file_2 목록을 작성해야하는 끝에 쓰기 행을 추가하여 테스트했지만 아무 것도 내뱉지 않았습니다.

3) 필자가 필요로하는 값은 파일 2의 목록에서 순서대로 호출 할 수 없으므로 (인덱스 0, 1, 8, 9 만 필요함) 필자는 데이터를 매핑 한 다음 인덱스를 출력하려고했습니다 범위 문제, 위 # 2에서 내 문제로 인해 이해할 수 있습니다.

나는이 오류를 제거하는 데 도움이 필요하며, 내 코드가 잘못되었거나 뭔가 실종 된 경우 어떤 도움을 주셔서 감사합니다.

+0

들여 쓰기를 위 코드에서 수정할 수 있습니까? –

+0

@MichaelPratt 물론! 죄송합니다. 눈치 채지 못했습니다 – ImmortalxR

+1

입력 파일에 두 줄 이상 있습니까? 그렇다면 두 파일을 모두 읽은 후 메모리에서 해당 내용을 읽어 메모리에있는 내용을 읽도록하십시오. 이 입력 줄의 순서에 대한 제약이 있습니까? – Gijs

답변

1

죄송합니다. 해결책을 고치지 말고 다른 테이크도 도움이 될 수 있습니다. 내가 너를 올바르게 이해한다면 이것은 내 코드가 될 것이다.

file_1_data = dict() 
file_2_data = dict() 
for filename, data in [('infile1.txt', file_1_data), ('infile2.txt', file_2_data)]: 
with open(filename) as f: 
    for line in f: 
     split_line = line.split()  
     first_int = int(split_line[0]) 
     rest_floats = [float(f) for f in split_line[1:]] 
     data[first_int] = rest_floats 

이제 당신은 키가 int있는 두 파일에 대한 사전, 그래서 당신은 그 비교할 수 있으며, 값은 수레의 목록입니다. 이 후에는 꽤 쉽습니다.

def filter_1(x): 
return x > 1 

def filter_2(x): 
return 4 < x < 100000 

with open('outfile.txt', 'wb') as outfile: 
for key in file_1_data: 
    if key in file_2_data: 
     #write a record, the first one 
     data_to_write = [str(f) for f in file_1_data[key] if filter_1(f)]  
     record = ' '.join([str(key)] + data_to_write) + '\n' 
     outfile.write(record) 
     #second one, do filtering here 
     data_to_write = [str(f) for f in file_2_data[key] if filter_2(f)] 
     record = ' '.join([str(key)] + data_to_write) + '\n' 
     outfile.write(record) 

희망이 있습니다. 제 생각에는 여기에 요점이 있다고 생각합니다. 약간 장황하거나 단순한 측면에 대해 걱정하지 마십시오. 그냥 혼자서 쉽게 사용하고 피할 수 있다면 반복하지 마십시오. 행운을 빕니다.

+0

예 출력이 정확히 OP에 넣었을 때와 똑같아 보이고 ID 번호가 일치해야합니다. 일치하는 항목이 있다면 – ImmortalxR

+0

죄송하지만 더 많이 읽을수록 이해할 수 있습니다. OP. 필터링이란 무엇입니까? 코드의 내용은 게시 한 샘플 데이터와 실제로 맞지 않습니다. 그리고 각 입력 파일에는 실제로 한 줄만 있습니다. 항상 첫 번째 열에 같은 정수가 있습니까? – Gijs

+0

내 다른 의견이이 문제를 해결한다고 생각합니다 :) – ImmortalxR

1

문자열을 filter_func_1filter_func_2으로 전달한 다음 람다 내부의 정수와 비교합니다. 그러나 숫자와 문자열을 비교할 때 비교가 축약됩니다. 숫자는 항상 문자열보다 앞서는 것으로 간주됩니다 (구현에 따라 다르며 CPython 동작을 가정합니다). 따라서 첫 번째 람다는 항상 True과 두 번째 False을 반환 할 것입니다. 따라서 코드에서 필터로 작동하지 않습니다.

전달한 문자열을 정수 또는 부동 소수점으로 변환해야합니다.:

filter_func_1 = lambda x: float(x) >= 15 

또는 입력기를 필터로 전달하기 전에 입력을 변환 할 수 있습니다. 두 경우 모두 입력을 숫자 유형으로 변환 할 수 없을 때 수행 할 작업에 대해 생각해야합니다.

숫자 유형으로 변환하면 앞에는 0이 제거됩니다. 두 번째 문제는 도움이 될 수도 있고 도움이되지 않을 수도 있지만, 코드의이 부분을 변경하기 전까지는 결과를 얻지 못할 수도 있습니다.

+0

그 통찰력에 감사드립니다. 내가 언급 한 방식으로 어떻게 변화시킬 것인가에 대한 도움이 필요하십니까? – ImmortalxR

+1

각 데이터에'int()'또는'float()'을 적용하고 싶을 것입니다 (문서는 [here] (http://docs.python.org/2/library/functions.html)를보십시오)). 모든 float을 사용하는 것이 행복하다면,'splt_file_1 = map (float, line_1.split())'과 같은 것을 쓸 수 있습니다. – Alp

+0

이 코드를 적용하면 잘 작동하지만 파일 2의 특정 부분을 꺼내야합니다. itemgetter를 사용하여이 작업을 수행하고 있는데 이것이 내가 가진 것입니다. \t splt_file_2 = map (float, line_2 .split()) \t splt_2_Data = map (itemgetter (0, 1, 8, 9), splt_file_2) 그러나 float에 getitem 속성이 없다는 오류가 발생합니다. 어떻게 해결할 수 있습니까? – ImmortalxR