큰 파일 (1 억 줄의 탭 구분 값 - 약 1.5GB 크기)이 있습니다. 필드 중 하나를 기준으로 정렬하는 가장 빠른 방법은 무엇입니까?큰 텍스트 데이터 정렬
하이브를 시도했습니다. 이 파이썬을 사용하여 더 빨리 수행 할 수 있는지보고 싶습니다.
큰 파일 (1 억 줄의 탭 구분 값 - 약 1.5GB 크기)이 있습니다. 필드 중 하나를 기준으로 정렬하는 가장 빠른 방법은 무엇입니까?큰 텍스트 데이터 정렬
하이브를 시도했습니다. 이 파이썬을 사용하여 더 빨리 수행 할 수 있는지보고 싶습니다.
* nix sort
프로그램을 사용 해본 적이 있습니까? 원시 측면에서는 대부분의 Python 스크립트보다 빠를 것입니다.
사용 -t $'\t'
는 탭으로 구분하면 출력에 새 파일로 결과를 원하는 경우 n
필드 번호, -o outputfile
있는 필드를 지정하려면 -k n
을 있다고 지정합니다. 예 :
sort -t $'\t' -k 4 -o sorted.txt input.txt
이 다음에 관심이 필드에서 인덱스를, 내가 좋은 관계형 데이터베이스에 파일을 저장하는 것 sorted.txt
그 결과를 자사의 4 번째 필드에 input.txt
를 정렬 및 출력 것인가 주문한 품목을 읽으십시오.
당신은 파일에 대한 메모리 인덱스 구축하려는 : 만들 빈 목록을
open
목록에서f.readline()
를 사용하여 읽을 파일 저장 정렬 할 값 (line.split('\t').strip()
으로 추출)과 파일의 줄 오프셋 (f.readline()
에 호출하기 전에 f.tell()
을 호출하여 얻을 수있는)로 구성된 튜플close
파일sort
그런 다음, 정렬 된 파일을 인쇄 파일을 다시 열어 목록의 각 요소에 대해, 읽기, 줄의 시작 부분에 f.readline()
을 파일 포인터를 이동 f.seek(offset)
을 사용하는 목록 라인 및 print
라인.
최적화 : 인쇄 단계에서 f.read(length)
을 사용할 수 있도록 목록의 줄 길이를 저장할 수 있습니다. (가독성을 위해 최적화 된 속도를하지 않음)
샘플 코드 : 최대 메모리에 정렬 할 수있는 파일로
def build_index(filename, sort_col):
index = []
f = open(filename)
while True:
offset = f.tell()
line = f.readline()
if not line:
break
length = len(line)
col = line.split('\t')[sort_col].strip()
index.append((col, offset, length))
f.close()
index.sort()
return index
def print_sorted(filename, col_sort):
index = build_index(filename, col_sort)
f = open(filename)
for col, offset, length in index:
f.seek(offset)
print f.read(length).rstrip('\n')
if __name__ == '__main__':
filename = 'somefile.txt'
sort_col = 2
print_sorted(filename, sort_col)
분할. 메모리에있는 각 파일을 정렬하십시오. 그런 다음 결과 파일을 병합하십시오.
병합 할 각 파일의 일부를 읽음으로써 병합합니다. 병합 된 결과를 위해 충분한 공간을 메모리에 남겨 두는 각 파일의 동일한 양. 한 번 병합이 저장합니다. 병합 된 데이터 블록을 파일에 반복적으로 추가.
이렇게하면 파일 입/출력이 최소화되고 디스크의 파일을 중심으로 이동합니다.
unix sort 명령은 실제로 매우 강력한 도구입니다. 정렬 할 필드의 형식 (숫자, 날짜 등) 및 프로그램에서 할당 할 수있는 메모리 양을 제어하고 필요한 경우 분할 + 병합 정렬을 수행 할 수 있습니다. –
알렉스 예를 들려 줄 수 있습니까? 정렬 프로그램 자체는 40 분 정도 걸리는 꽤 오랜 시간이 걸립니다. 이것은 메모리 할당이나 디스크 IO와 관련이있을 수 있습니다. 병목 현상이 무엇인지 파악하는 방법을 모르겠지만 제안이 유용 할 것으로 짐작됩니다. – fodon
위의 솔루션에서 하나의 오류 : 두 번째 필드 만 사용하려면 하나는 -k 2,2 ...가 필요합니다. 따라서 제로 인덱싱되지 않습니다 (적어도 쿠분투 11.04 버전의 정렬에는 해당되지 않음). – fodon