2012-08-02 4 views
1

스택 오버플로에서 비슷한 질문을 몇 개 발견했지만 필자의 경우 조언이 도움이 될 수 있다고 생각합니다.파일에서 숫자 목록을 읽는 가장 빠른 방법

파일에 약 80,000 개의 실제 값 목록을 저장하고 나중에 읽어야합니다.

첫째, 나는 cPickle을 시도했지만 독서 시간은 호소하지 않은 :

>>> stmt = """ 
with open('pickled-data.dat') as f: 
    data = cPickle.load(f) 
""" 
>>> timeit.timeit(stmt, 'import cPickle', number=1) 
3.8195440769195557 

가 그럼 난 일반 텍스트 빨리 읽기 (의미가 허용하는 cPickle 때문에, 숫자를 저장하는 것은 걱정해야한다는 것을 발견 많은 것) :

>>> stmt = """ 
data = [] 
with open('text-data.dat') as f: 
    for line in f: 
     data.append([float(x) for x in line.split()]) 
""" 
>>> timeit.timeit(stmt, number=1) 
1.712096929550171 

이 좋은 개선이다,하지만 난 다른 언어로 작성된 프로그램은 상당히 빠른 파일에서 유사한 데이터를 읽을 수 있기 때문에 나는 아직도, 어떻게 든 그것을 최적화 수 있다고 생각.

아이디어가 있으십니까? NumPy와 배열이 가능한 경우

+1

많은 목록을 저장하는 경우 sqlite 데이터베이스가 더 나은 데이터 구조가 아니겠습니까? – BrtH

+0

'csv' 모듈의 리더를 아직 사용해 보지 않으셨습니까? 당신이 부르는 수동 분할을 피할 수 있습니다. – jmetz

+1

@BrtH 데이터베이스가 과도한 것처럼 보입니다.이 목록을 모두로드하면됩니다. – erickrf

답변

2

것은, numpy.fromfile 가능성이

또는 당신이 struct에 조금 더 잘 할 수있는 것 같아 (여기 somewhat related question 난 그냥 몇 일 전에 요청의) 파일을 읽을 수있는 가장 빠른 옵션이 될 것입니다 , 나는 그것을 테스트하지 않았지만 :

import struct 
def write_data(f,data): 
    f.write(struct.pack('i',len())) 
    for lst in data: 
     f.write(struct.pack('i%df'%len(lst),len(lst),*lst)) 

def read_data(f): 
    def read_record(f): 
     nelem = struct.unpack('i',f.read(4))[0] 
     return list(struct.unpack('%df'%nelem,f.read(nelem*4))) #if tuples are Ok, remove the `list`. 

    nrec = struct.unpack('i',f.read(4))[0] 
    return [ read_record(f) for i in range(nrec) ] 

이것은 4 바이트 부동 소수점으로 데이터를 저장하는 것이 충분하다고 가정합니다. 실제 배정도 숫자를 원할 경우 format 문을 f에서 d로 변경하고 nelem*4nelem*8으로 변경하십시오. 약간의 이식성 문제가있을 수 있습니다 (endianness 및 sizeof 데이터 유형 예를 들어).

+0

나는 numpy fromfile이 상대적으로 최적화되어 있으며 구조가 허용하는 상황보다 나은 해결책이라고 생각합니다. – jmetz

+0

@mutzmatron - 예, 아마 - 너무 많이 차이가 있어서는 안됩니다. 나는 그들이 거의 같은 일을 할 것이라고 확신한다. numpy는 순차적 메모리에 객체를 넣을 수 있다는 장점이있다. (본질적으로 오직 포인터 1 개와 포인터 1 개를 할당하여 포인터를 계산할 필요가있다.) 반면에 구조체는 여전히 하나의 블럭을 할당 할 것이지만, 읽히는 각 플롯에 대한 포인터가 필요하므로 약간의 추가 작업이 필요합니다. 어쨌든, 나는 ascii 텍스트를 float로 변환하는 것보다 빠르다는 것을 기대한다. (모두 un-typed python 프레임 워크 내에서 이루어진다.) – mgilson

+0

감사합니다.'numpy.fromfile'은 0.02 초 정도 걸렸습니다. – erickrf

관련 문제