2013-10-07 3 views
1

하나의 열이 있지만 620 만 개의 행을 포함하는 CSV 파일이 있습니다. 모두 6 자와 20 자 사이의 문자열을 포함합니다. 일부 문자열은 중복 (또는 그 이상) 항목에서 발견 될 것이며 새로운 CSV 파일에이 문자열을 쓰고 싶습니다. 약 1 백만 개의 고유하지 않은 문자열이 있어야합니다. 그게 사실입니다. 그러나 6 백만 항목의 사전을 통해 계속 검색하는 데는 시간이 걸리며, 어떻게해야하는지에 대한 조언을 주시면 감사하겠습니다. 지금까지 작성한 모든 스크립트는 내가 한 몇 가지 타이밍에 따라 적어도 일주일이 걸립니다 (!).매우 큰 csv 파일에서 검색 최적화

첫 번째 시도 :

in_file_1 = open('UniProt Trypsinome (full).csv','r') 
in_list_1 = list(csv.reader(in_file_1)) 
out_file_1 = open('UniProt Non-Unique Reference Trypsinome.csv','w+') 
out_file_2 = open('UniProt Unique Trypsin Peptides.csv','w+') 
writer_1 = csv.writer(out_file_1) 
writer_2 = csv.writer(out_file_2) 

# Create trypsinome dictionary construct 
ref_dict = {} 
for row in range(len(in_list_1)): 
    ref_dict[row] = in_list_1[row] 

# Find unique/non-unique peptides from trypsinome 
Peptide_list = [] 
Uniques = [] 
for n in range(len(in_list_1)): 
    Peptide = ref_dict.pop(n) 
    if Peptide in ref_dict.values(): # Non-unique peptides 
     Peptide_list.append(Peptide) 
    else: 
     Uniques.append(Peptide) # Unique peptides 

for m in range(len(Peptide_list)): 
    Write_list = (str(Peptide_list[m]).replace("'","").replace("[",'').replace("]",''),'') 
    writer_1.writerow(Write_list) 

두 번째 시도 :

in_file_1 = open('UniProt Trypsinome (full).csv','r') 
in_list_1 = list(csv.reader(in_file_1)) 
out_file_1 = open('UniProt Non-Unique Reference Trypsinome.csv','w+') 
writer_1 = csv.writer(out_file_1) 

ref_dict = {} 
for row in range(len(in_list_1)): 
    Peptide = in_list_1[row] 
    if Peptide in ref_dict.values(): 
     write = (in_list_1[row],'') 
     writer_1.writerow(write) 
    else: 
     ref_dict[row] = in_list_1[row] 

편집 : 여기에 CSV 파일에서 몇 줄의 :

SELVQK 
AKLAEQAER 
AKLAEQAERR 
LAEQAER 
LAEQAERYDDMAAAMK 
LAEQAERYDDMAAAMKK 
MTMDKSELVQK 
YDDMAAAMKAVTEQGHELSNEER 
YDDMAAAMKAVTEQGHELSNEERR 
+0

게시하시기 바랍니다 몇 가지 전형적인 라인과 같은 일을 할 것입니다. – unutbu

+1

문제는 전체 파일을 한 번에 읽는 것이므로 다른 사람에게 좋지 않습니다. 중복 된 줄만 출력하면된다. 'uniq -Di somefile.txt> duplicate_lines.txt' –

+0

이상한 쉼표로 구분 된 값 (csv)은 분리 할 것이 없다. hehe! 나는 이것을 csv 파일로 생각하지 않을 것이다. –

답변

2

첫 번째 힌트 : 파이썬은 게으른에 대한 지원을하고 평가, 거대한 데이터 세트를 다룰 때 더 잘 사용하십시오. 그래서 : 당신의 csv.reader 이상

  • 으로 반복하는 대신 거대한 메모리 목록을 빌딩의,
  • 는 범위와 큰 메모리 목록을 작성하지 않는다 - 당신이 항목 인덱스 모두를 필요로 대신하는 경우 enumate(seq)를 사용 , 인덱스가 필요없는 경우 시퀀스의 항목을 반복합니다.

두 번째 힌트하십시오 dict (해시 테이블)를 사용하여의 주요 포인트는 ... 이 아닌 값을 조회 할 수 그래서 목록으로 사용되는 거대한 딕셔너리를 구축하지 않는 것입니다.

세 번째 힌트 : "이미 본"값을 저장하는 방법을 원하면 Set을 사용하십시오.

+0

감사! 집합을 사용하고 독자를 반복하는 대신 정말 멋지게 물건을 빠르게 - 스크립트는 이제 실행하는 데 약 1 분 정도 걸립니다. 왜 정확히/얼마나 빠른지 알고 싶습니다. 조금 더 빠르지는 않지만 엄청나게 빠릅니다! – Sajber

+0

첫 번째 명백한 이유 : dict (주로 배열로)를 사용하는 방식은 O (n) 검색 시간 (및 매우 큰 'n'값)을 의미합니다. 집합을 사용하면 O (1) 조회 시간이 있습니다. 두 번째 가능한 이유 (하지만 이것은 자연스러운 추측입니다) : 데이터 세트의 크기가 2 개의 메모리 내 복사본 (사용자 목록 다음)이 사용 가능한 RAM을 모두 먹었을 수 있으며 컴퓨터가 스왑을 사용하도록 강제 할 수 있습니다. . –

+0

좋아, 그게 분명해! – Sajber

0

저는 파이썬에서는별로 좋지 않습니다. 그래서 'in'이 어떻게 작동하는지 모르지만 알고리즘은 n²에서 실행되는 것 같습니다. 목록을 읽은 후 정렬을 시도하십시오. n log (n)에 algo가있는 경우 quicksort와 같이 더 잘 작동합니다. 목록이 정렬되면 목록의 연속 된 두 요소가 같은지 확인해야합니다.

따라서 n을 읽으면 n log (n) (가장 좋음)로 정렬되고 n은 비교됩니다.

2

Numpy와 함께하십시오. 대략 :

import numpy as np 
column = 42 
mat = np.loadtxt("thefile", dtype=[TODO]) 
uniq = set(np.unique(mat[:,column])) 
for row in mat: 
    if row[column] not in uniq: 
     print row 

당신은 numpy.savetxt를 사용하여 출력 스테이지와 문자 배열 연산자를 벡터화 수 있지만 아마도 매우 큰 차이를하지 않습니다.

0

비록 내가 수치스러운 해결책이 최고라고 생각하지만 주어진 예를 빠르게 할 수 있는지 궁금합니다. 제안 사항은 다음과 같습니다.

  • skip csv.(1MEG을 읽을 64K 아마 좋은 쓰기)
  • 인덱스로 DICT 키를 사용하여 독자의 비용과 단지
  • 더 큰 파일 버퍼 크기를 사용
  • 줄 바꿈를 해결하기 위해 필요한 추가 검사를 건너
  • RB 라인을 읽기 - 키를 조회 값 조회 나는 NumPy와 사람이 아니에요

보다 훨씬 더 빨리, 그래서 나는 당신의 CSV의

in_file_1 = open('UniProt Trypsinome (full).csv','rb', 1048576) 
out_file_1 = open('UniProt Non-Unique Reference Trypsinome.csv','w+', 65536) 

ref_dict = {} 
for line in in_file_1: 
    peptide = line.rstrip() 
    if peptide in ref_dict: 
     out_file_1.write(peptide + '\n') 
    else: 
     ref_dict[peptide] = None 
관련 문제