2010-06-23 7 views
1

은 난의 패턴 정보를 가진 파일이 있습니다 변수 "A"값으로하고, 행 번호를받을 필요가Bisect는 목록 대신 Dict을 사용하여 적용 할 수 있습니까?

.343423 1 
.434322 1 
.453434 1 
.534342 1 

같은 크기 정렬 된 주문입니다 각 행과 행을하는 그것을 첫 번째 열의 값과 비교하여 "a"에 가장 근접한 값입니다.

지금까지 1 열 요소를 목록으로 복사 한 다음 bisect 메서드를 사용하여 row_num을 얻었습니다.하지만이 작업을 수행해야합니다. 많은 시간을 ... 나는 매회 목록에 약 4000 요소를 복사해야하기 때문에 고통스럽게 천천히되었다.

그래서 지금 나는 데이터 구조 대신에 데이터 구조 대신 dict를 사용하여 생각하는 것이 더 빠를 것입니다.하지만 가능한 경우 bisect에서 dict을 사용할 수 있는지 여부는 알 수 없습니다. 어떻게하면이 경우에 사용할 수 있습니까? if not possible any methods 빠른 목록에 데이터를 로딩하는 것이 더 빠르다. 감사합니다 ...

+0

파일 형식을 제어 할 수 있습니까? 아마도이 문제의 배경으로 모든 OP 질문을 검토하는 대신 –

+0

대신 이진 형식을 사용할 수 있습니다. – SilentGhost

답변

0

왜 요소를 복사해야하는지 알 수 없습니다. 이것은 느린 부분입니다. 시작할 때 목록을 한 번로드 한 다음 항상 같은 목록을 사용할 수 있습니까?

dict은 어쨌든 목록보다 느릴 것입니다. (확실하지는 않지만 hash_map으로 구현되어 있으므로 순서가 없으므로 bisect를 사용할 수 없습니다).

+0

그 differrent 파일입니다 그래서 매번 열리는 오전 목록이 다를 수 있습니다 .. 그래서 어떤 제안 – kaki

+0

그럼 그 기회를 개선하는 것입니다! 여기서 가장 큰 문제는 디스크 액세스가 다른 어떤 것보다 느리다는 것입니다. 모든 데이터를 한 번에로드하고 sqlite 데이터베이스에 저장하는 방법에 대해 생각해보십시오.하지만 파일에 액세스 할 때마다 항상 빠른 속도로 수행 할 필요는 없습니다. –

0

딕테이션은 순서가 지정되지 않으므로이 딕트를 사용하면 의미가 없습니다.

나는 몇 가지 옵션을 생각할 수 있습니다

1) (키, 값) 튜플의 정렬 된 목록의 데이터를 유지합니다. 이렇게하면 bisect를 사용하여 가장 가까운 요소를 찾을 수 있습니다. 이것은 이것이 당신이 목록으로하고 싶은 유일한 일이고 목록이 시간이 지남에 따라 많이 변하지 않는다면 (이것은 매번 의지해야 할 것이기 때문에 비용이들 것입니다) 괜찮습니다.

2) 균형 이진 트리 데이터 구조를 사용하십시오 - 여러 개의 Python implementations available on PyPi이 있습니다. bisect와 같은 가장 가까운 요소를 찾을 수있는 동안 사전과 같은 의미를 부여합니다. PyPi 검색의 첫 번째 항목은 bintrees으로 원하는 모든 작업을 수행하는 것처럼 보입니다. 사전처럼 작동하지만 주어진 값 앞뒤에 항목을 가져 오는 추가 메서드가 있습니다. 그러면 가장 가까운 번호를 효율적으로 찾을 수 있습니다.

0

전체 파일을 읽는 경우 목록을 검색해야하므로 (O (lg n)) 사전은 크기에 관계없이 빠른 검색을 제공하지만 사전은 목록보다 빠릅니다 (O (1)). 물론 사전에 이분 탐색 (이진 탐색)을 사용하지 않을 것입니다. 특정 파일에서 한 행만 찾고있는 경우에도 그렇게 할 필요가 없습니다. 찾고있는 행을 찾을 때까지 파일을 읽을 수 있습니다.

파일 당 조회 수가 적은 경우 파일 자체에서 직접 이진 검색을 수행하면 더 빨리 검색 할 수 있습니다. 파일이 정렬되어 있고 각 레코드의 길이가 같기 때문에 검색에 필요한 파일의 바이트 단위로 읽는 코드를 쉽게 작성할 수 있습니다.

+0

친절하게도 일부 샘플 코드를 제공 해달라고 요청합니다 ... 전체 코드가 아니라면 ... 분명히 의미있는 것을 얻을 수는 없지만 더 빨리 제안 된 것을 얻을 수는 없습니다 ... 그렇다면 작성 방법에 대해 조금 더 안내 할 수 있습니다. 코드 ... thnq – kaki

1

전체 파일을 읽지 않고 bisect을 사용하는 방법입니다.OS는 관계없이 필요 이상으로 파일의 훨씬 더 읽기 끝날 것입니다, 그래서 당신은 충분히 데이브 커비의 솔루션과 유사

from os import SEEK_END 
from bisect import bisect 

class ListProxy(object): 
    def __init__(self, f): 
     self.f = f 
     self.line_len = len(f.readline()) 
     self.f.seek(0, SEEK_END) 
     self.num_lines = self.f.tell()//self.line_len 

    def __len__(self): 
     return self.num_lines 

    def __getitem__(self, idx): 
     self.f.seek(idx*self.line_len) 
     return float(self.f.read(7)) 

with open("data.txt") as f: 
    lp = ListProxy(f)  
    num = .44 
    idx = bisect(lp, num) 
    if idx != 0 and num - lp[idx-1] < lp[idx] - num: 
     idx -=1 
    print num, idx 
4

, PyPIsortedcontainers 모듈을 고려 큰 data.txt 때까지 성능 향상을 볼 수 없습니다. 그것은 순수한 파이썬이고 fast이며 키 위에 SortedDict type with bisect을 제공합니다. 또한 파일의 대량로드 데이터를위한 균형 이진 트리 유형보다 훨씬 빠릅니다. 귀하의 경우에는

,이 같은 작동 될 수 있습니다

from sortedcontainers import SortedDict 
with open('data.txt') as fptr: 
    sd = SortedDict(map(int, line[1:].split()) for line in fptr) 

# sd now contains key, value pairs corresponding to the columns in your data file 
# Lookup index of desired key: 

pos = sd.bisect(434323) 

# pos points to the index of the key 434322 
# get that key: 

key = sd.iloc[pos] 

# now get the value: 

value = sd[key] 

작업을 : 양분, 인덱싱, 키 조회는 sortedcontainers 모듈 내에서 매우 빠르게 모두. 이 솔루션을 사용하려면 파일의 전체 내용을 메모리에 보관할 수 있어야합니다.

관련 문제