2017-12-31 13 views
0

저는 파이썬을 처음 사용하고 아직 어떤 최적화 작업도하지 않았습니다. 나는 그들 자신이 이미 꽤 큰 파일을 가지고 가려고 시도하고있다. 아마 50-100GB에 가까워지는 하나의 커다란 파일을 결합하여 내 추측이 될 것이다. 어쨌든 내가 가지고있는 것보다 더 많은 메모리. 아래 코드가 주어졌고 작은 파일에도 잘 작동합니다. 내 유스 케이스의 실제 파일을 덮어 쓰려고하면 컴퓨터가 완전히 잠길 것입니다.일부 플랫 파일을 결합한이 코드를 더 빠르게 실행할 수 있습니까?

나는 팬더가 빠르다는 것을 알고 있습니다. 데이터 프레임이 메모리에 저장된다고 추측합니다. 그게 사실이라면 아마 여기에있는 것들을 망칠 것입니다. 디스크에 쓰기 전에 데이터 프레임에 모든 것을 보관하려고 시도하는 대신 디스크에 흘리거나 기존 파일에 쓸 수있는 종류 또는 메커니즘이 있습니까? 아니면 내가 생각하지 못했던 또 다른 옵션일까요?

import pandas as pd 
import os 

file_masks = ['fhv', 'green', 'yellow'] 


def combine_files(file_mask): 

    csvfiles = [] 
    for path, directories, files in os.walk('TaxiDriveData/'): 
     csvfiles.extend([os.path.join(path, fn) for fn in files if fn.startswith(file_mask)]) 

    df = pd.concat((pd.read_csv(fn) for fn in csvfiles)) 
    df.to_csv(os.path.join('TaxiDriveCombinedData', file_mask + '_trip_data.csv'), index=False) 

for m in file_masks: 
    combine_files(m) 
+2

분배 팬더와 :

는 다음과 같은 것을 시도 할 수 있습니다. 아마도 헤더를 건너 뛰어도 괜찮습니다. –

답변

1

여기에는 모든 것을 메모리에로드하지 않는 비 판다 솔루션이 있습니다. 나는 그것을 테스트하지는 않았지만 효과가있다.

import os 

file_masks = ['fhv', 'green', 'yellow'] 


def combine_files(file_mask): 

    with open(os.path.join('TaxiDriveCombinedData', file_mask + '_trip_data.csv'),'w') as fout: 
     csvfiles = [] 
     for path, directories, files in os.walk('TaxiDriveData/'): 
      csvfiles.extend([os.path.join(path, fn) for fn in files if fn.startswith(file_mask)]) 

     for in_file in csvfiles: 
      with open(in_file,'r') as fin: 
       # f.next() # comment this out if you want to remove the headers 
       for line in fin: 
        fout.write(line) 


for m in file_masks: 
    combine_files(m) 
+0

우수! 그게 작동하고 테스트 파일에 내 컴퓨터를 고정하지 않았다. 전체 데이터 세트에서 실행 해 보겠습니다. 그게 작동한다면, 나는 이것을 답으로 표시 할 것입니다. –

0

파이썬을 사용하지 않아도됩니다. 리눅스 시스템에는 파일을 결합 할 수 있고 최적화되었거나 매우 효율적으로 수행 할 수있는 매개 변수가 있습니다. 예를 들어, join, cat, dd ...

이것은 가장 효율적인 옵션은 아니지만 : 당신은 내가 읽고 대신 라인으로 파일 라인을 읽는 덩어리에있는 파일을 작성하는 것이 좋습니다 고성능 파이썬 버전을 원하는 경우

cat input/*.csv > output/combined.csv 

.

가장 큰 문제는 I/O이며 하드 디스크의 더 큰 정보 블록을 읽고 쓰면이 문제를 최적화 할 수 있습니다. 하드 드라이브와 파일 시스템의 최적 크기로 읽고 쓰는 경우 차이점을 알 수 있습니다. 예를 들어, 최신 HDD의 공통 블록 크기는 4096 바이트 (4KB)입니다. 당신은 그것이 사용하는 모든 CSV 년대를 구문 분석 할 경우 모두

NEW_LINE = '\n' 

def read_in_chunks(f, chunksize=4096): 
    while True: 
     chunk = f.read(chunksize) 
     if not chunk: 
      break 
     yield chunk 

(...) 

fout = open('output.csv', 'w') 

for fname in files: 
    with open(fname) as fin: 
     buffer = '' 
     for chunk in read_in_chunks(fin): 
      buffer += chunk 
      lines, tmp_buffer = buffer.rsplit(NEW_LINE, 1) 
      lines += NEW_LINE # rsplit removes the last new-line char. I re-add it 
      fout.write(lines) 
      buffer = tmp_buffer 

fout.close() 
관련 문제