2017-05-01 5 views
1

약 1B 행의 큰 csv 파일을 읽었습니다. 날짜를 파싱 할 때 문제가 발생했습니다. 파이썬은 처리 속도가 느립니다.대용량 파일의 구문 분석 속도를 향상시키는 방법이 있습니까?

파일의 한 줄은 '20170427,20:52:01.510,ABC,USD/MXN,1,OFFER,19.04274,9000000,[email protected]@8653948257753368229,0.0\n'

난 단지 데이터를 보면 , 그것은 1 분 소요, 다음과 같습니다.

t0 = datetime.datetime.now() 
i = 0 
with open(r"QuoteData.txt") as file: 
    for line in file: 
     i+=1 
print(i) 
t1 = datetime.datetime.now() - t0 
print(t1) 

129908976 
0:01:09.871744 

그러나 datetime을 구문 분석하려고하면 8 분이 걸릴 것입니다.

t0 = datetime.datetime.now() 
i = 0 
with open(r"D:\FxQuotes\ticks.log.20170427.txt") as file: 
    for line in file: 
     strings = line.split(",") 

     datetime.datetime(
      int(strings[0][0:4]), # %Y 
      int(strings[0][4:6]), # %m 
      int(strings[0][6:8]), # %d 
      int(strings[1][0:2]), # %H 
      int(strings[1][3:5]), # %M 
      int(strings[1][6:8]), # %s 
      int(strings[1][9:]), # %f 
     )  

     i+=1 
print(i) 
t1 = datetime.datetime.now() - t0 
print(t1) 

129908976 
0:08:13.687000 

split() 약 1 분이 소요되고 날짜 파싱 약 6 분이 걸린다. 이 문제를 개선하기 위해 할 수있는 일이 있습니까?

+0

[gevent] (http://www.gevent.org/)를 살펴볼 수 있습니다. 여러 스레드 사이에서 프로세스를 분할 할 수 있습니다 - 실제로 원하는만큼 많은 CPU/mem 대문자를 조심하십시오. – Neil

+0

날짜를 실제 datetime 객체로 변환해야합니까? – Grimmy

+0

''''line [: s.index (',')]''날짜를 더 빨리 얻으려면? 또는 각 행의 형식이 동일하면 하드 코딩 된 인덱스로 슬라이스하십시오. ''line [0 : 8]''. – Grimmy

답변

2

@TemporalWolf는 ciso8601을 사용하는 것이 좋습니다. 나는 그것을 들어 본 적이 없기 때문에 나는 그것을 시도해 볼 것이라고 생각했다.

먼저 샘플 랩톱으로 벤치마킹했습니다. 그 정확한 줄의 1 천만 행을 가진 CSV 파일을 만들었고 모든 것을 읽는 데 약 6 초가 걸렸습니다. 귀하의 날짜 분석 코드를 사용하면 최대 8 초가 걸렸습니다. 그런 다음 파일 크기를 1 백만 행까지 줄였습니다. 0.6 초 만에 읽을 수 있었고 날짜를 구문 분석하여 4.8 초 만에 모든 것이 올바르게 보였습니다.

은 그 때 나는 ciso8601로 전환하고, 거의 마술처럼 1 백만 행에 대한 시간은 약 1.9 초 4.8 초에서 갔다 : 데이터가 거의 ISO8601 형식으로 이미

import datetime 
import ciso8601 

t0 = datetime.datetime.now() 
i = 0 
with open('input.csv') as file: 
    for line in file: 
     strings = line.split(",") 
     d = ciso8601.parse_datetime('%sT%s' % (strings[0], strings[1])) 
     i+=1 
print(i) 
t1 = datetime.datetime.now() - t0 
print(t1) 

주 . 나는 중간에 "T"와 함께 날짜와 시간을 붙여야했습니다.

+0

''split''도 지속 시간에 15 %를 더합니다. 그가 단지 날짜를 검사하고 싶다면''line [0 : 8]'' – Grimmy

+0

csv 모듈이 속도를 올릴 수 있습니까? – eri

+0

"% s % s"% (str1, str2)'는 문자열을 연결하는 더 느린 방법 중 하나입니다. 사실,이 경우에는 직선 연결이 더 빠릅니다.'parse_datetime (strings [0] + ''strings [1])'. 또한,'from ciso8601 import parse_datetime'은 매 호출마다 참조를 검색하지 않아도되므로'ciso8601.parse_datetime()'과 비교하여 빠릅니다. Grimmy와 같이 문자열을 잘라내면 시간이 거의 절반으로 줄어 듭니다. 다른 최적화. 이러한 비교는 ** 버전에 따라 다릅니다 **. – TemporalWolf