2017-05-22 5 views
0

각 줄마다 다른 수정 규칙이 필요할 수 있으므로 상당히 큰 CSV 파일을 가지고 있습니다. 각 CSV 파일은 다른 CSV에 적절하게 작성해야합니다. 서식 지정.큰 CSV 파일을 읽고 형식을 지정한 다음 쓸 수 있습니다.

현재 내가 가진 :

import multiprocessing 

def read(buffer): 
    pool = multiprocessing.Pool(4) 
    with open("/path/to/file.csv", 'r') as f: 
     while True: 
      lines = pool.map(format_data, f.readlines(buffer)) 
      if not lines: 
       break 
      yield lines 

def format_data(row): 
    row = row.split(',') # Because readlines() returns a string 
    # Do formatting via list comprehension 
    return row 

def main(): 
    buf = 65535 
    rows = read(buf) 
    with open("/path/to/new.csv",'w') as out: 
     writer = csv.writer(f, lineterminator='\n') 
     while rows: 
      try: 
       writer.writerows(next(rows)) 
      except StopIteration: 
       break 

내가 map를 통해 멀티 프로세싱을 사용하고 발전기와 메모리 과부하를 방지하고있어하더라도, 그것은 여전히 ​​40,000 선을 처리하기 위해 2 분 동안 저를 잘합니다. 솔직히 그렇게 많이 받아 들여서는 안됩니다. 심지어 생성기 출력에서 ​​중첩 된 목록을 생성하고 한 번에 하나의 큰 파일로 데이터를 쓰려고 시도했습니다. 이는 청크 별 방법과 마찬가지로 오래 걸립니다. 여기서 내가 뭘 잘못하고 있니?

답변

0

나는 그것을 알아 냈습니다.

먼저 내 format_data() 함수에서 문제가 발생했습니다. 데이터베이스 연결을 호출 할 때마다 데이터베이스 연결을 구성하고 반복 할 때마다 닫았습니다.

멀티 스레딩을 지원하는 기하 급수적 인 빠른 조회 테이블 사전을 통해 기본 매핑을 만들어 해결했습니다.

그래서, 내 코드는 다음과 같습니다

import multiprocessing 

def read(buffer): 
    pool = multiprocessing.Pool(4) 
    with open("/path/to/file.csv", 'r') as f: 
     while True: 
      lines = pool.map(format_data, f.readlines(buffer)) 
      if not lines: 
       break 
      yield lines 

def format_data(row): 
    row = row.split(',') # Because readlines() returns a string 
    # Do formatting via list comprehension AND a dictionary lookup 
    # vice a database connection 
    return row 

def main(): 
    rows = read(1024*1024) 
    with open("/path/to/new.csv",'w') as out: 
     while rows: 
      try: 
       csv.writer(f, lineterminator='\n').writerows(next(rows)) 
      except StopIteration: 
       break 

내가 미만 30 초에서 ~의 1백50메가바이트 파일을 구문 분석 할 수 있었다. 일부 교훈은 다른 사람들이 희망적으로 배울 수 있도록 여기에서 배웠습니다.