저는 몇 달 동안 프로그래밍을 해왔으므로 전문가는 아닙니다. 두 개의 거대한 텍스트 파일 (옴니 ~ 20GB, ~ 2.5M 라인, dbSNP, ~ 10GB, ~ 60M 라인)이 있습니다. 그것들은 처음 몇 줄을 가지고 있는데, 탭으로 구분 된 것은 아니지만 "#"(머리글)로 시작하고 나머지 줄은 탭으로 구분 된 열 (실제 데이터)로 구성됩니다.거대한 텍스트 파일의 데이터를 가져 와서 다른 거대한 텍스트 파일의 데이터를 효율적으로 대체하십시오 (Python)
각 줄의 처음 두 열은 염색체 번호와 염색체상의 위치를 포함하며 세 번째 열은 식별 코드를 포함합니다. "옴니"파일에는 ID가 없으므로 dbSNP 파일 (데이터베이스)에서 위치를 찾고 ID로 완료된 첫 번째 파일의 복사본을 만들어야합니다.
메모리 제한으로 인해 두 파일을 한 줄씩 읽고 마지막 줄에서 다시 읽기로 결정했습니다. 코드의 효율성에 만족하지 않습니다. 느릴 수 있기 때문입니다. 나는 경험이 부족하기 때문에 내 잘못이라고 확신한다. 파이썬을 사용하여 더 빠르게 만들 수있는 방법이 있습니까? 문제는 파일을 열거 나 닫을 수 있습니까?
나는 보통 그놈 터미널이 같은 (파이썬 2.7.6, 14.04 우분투)에서 스크립트를 실행:
Replace.err파이썬 -u Replace_ID.py> Replace.log 2>
미리 감사드립니다. 무
...
#CHROM POS ID REF ALT ...
1 534,247. CT ...
...
dbSNP (dbSNP example)
...
#CHROM POS ID REF의 ALT ...
1 10019 rs376643643 TA T ... 출력은 있지만 positi 후의 RS의 ID와, 옴니 파일과 완전히 동일해야
... 에.
코드 :
SNPline = 0 #line in dbSNP file
SNPline2 = 0 #temporary copy
omniline = 0 #line in omni file
line_offset = [] #beginnings of every line in dbSNP file (stackoverflow.com/a/620492)
offset = 0
with open("dbSNP_build_141.vcf") as dbSNP: #database
for line in dbSNP:
line_offset.append(offset)
offset += len(line)
dbSNP.seek(0)
with open("Omni_replaced.vcf", "w") as outfile:
outfile.write("")
with open("Omni25_genotypes_2141_samples.b37.v2.vcf") as omni:
for line in omni:
omniline += 1
print str(omniline) #log
if line[0] == "#": #if line is header
with open("Omni_replaced.vcf", "a") as outfile:
outfile.write(line) #write as it is
else:
split_omni = line.split('\t') #tab-delimited columns
with open("dbSNP_build_141.vcf") as dbSNP:
SNPline2 = SNPline #restart from last line found
dbSNP.seek(line_offset[SNPline])
for line in dbSNP:
SNPline2 = SNPline2 + 1
split_dbSNP = line.split('\t')
if line[0] == "#":
print str(omniline) + "#" + str(SNPline2) #keep track of what's happening.
rs_found = 0 #it does not contain the rs ID
else:
if split_omni[0] + split_omni[1] == split_dbSNP[0] + split_dbSNP[1]: #if chromosome and position match
print str(omniline) + "." + str(SNPline2) #log
SNPline = SNPline2 - 1
with open("Omni_replaced.vcf", "a") as outfile:
split_omni[2] = split_dbSNP[2] #replace the ID
outfile.write("\t".join(split_omni))
rs_found = 1 #ID found
break
else:
rs_found = 0 #ID not found
if rs_found == 0: #if ID was not found in dbSNP, then:
with open("Omni_replaced.vcf", "a") as outfile:
outfile.write("\t".join(split_omni)) #keep the line unedited
else: #if ID was found:
pass #no need to do anything, line already written
print "End."
테스트를 위해 자세한 정보를 제공해 주시겠습니까? 예를 들어 각 파일에 5 줄을 제공하고 교체 프로세스가 완료되었음을 나타내는 5 줄 출력을 제공합니까? 아마 당신이 제공하는 코드를 더 잘 이해할 수있을 것이며 또한 약간의 수정을 테스트하고 일관성을 검증 할 수있을 것입니다. –
@ ArthurVaïsese 귀하의 제안에 감사드립니다. 원본 메시지를 편집했습니다. 두 개의 링크 만 추가 할 수 있으므로 다음은 출력 파일 예제입니다. lucabetti.altervista.org/file/Output_example.vcf – 4Kinesis