barcode

번외편-코딩테스트 풀이

Coding/Python

코테 본다는 얘기는 못 들은 것 같고... 그냥 면접보다가 어디 실력 좀 볼까? 해서 나온거긴 한데... 
IDE도 셋업 안 된 상태에서 jupyter 데모로 봤었음... 
근데 Python을 안 쓰면 나한테 연락을 안 할것인데 이건 뭔 상황인지 모르겠고... 

거기다가 실습할 때 썼던 파일들 올릴랬는데 깃헙 뻑나서 오전중에는 그거랑 씨름함... 해결은 봤죠. 
참고로 어제 사용한 FASTAQ파일과 오늘 사용한 FASTAQ파일은 다릅니다. 이거 구하기도 개빡셈. 


모듈 모셔오기

from Bio import SeqIO
from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
import numpy as np
import pandas as pd

세번째줄 안불러도 됨 그거 쩌리예요
판다스 넘파이는 4, 5번 풀려고 부른거 

 

1. FastaQ 파일을 Fasta 파일로 변환해라

# FASTAQ file 불러오기
handle="/home/koreanraichu/sra_data_mo.fastq"
for record in SeqIO.parse(handle,"fastq"):
    print(record.id)
# FASTA파일로 쓰기
convert_fasta=SeqIO.convert(handle, "fastq", "/home/koreanraichu/sra_data_mo.fasta","fasta")

어제는 내 컴퓨터도 아니고 Jupyter 데모여서 파일 자체 확인을 못 했는데, 이런 상황에서 잘 됐나 확인할거면 SeqIO read로 불러와보자. SeqIO는 뭉텅이로 있으면 parse만 된다. (정확히는 parse+for)

 

(변환 후)

 

2. Fasta파일에서 A, T, G, C 세기

handle2="/home/koreanraichu/sra_data_mo.fasta"
for record2 in SeqIO.parse(handle2,"fasta"):
    print(Seq(record2.seq).count("A"))
    print(type(Seq(record2.seq).count("A")))
    # Count로 세는 건 되는데 합계를 안 내준다. int형인데 더해주질 않음.

정수형인데 왜 더하질 못하고 각개출력하니... 
내가 저 상태에서 리스트로 만들려고 append 했더니 아 실패요. 그것도 각개 리스트로 나오고 A=A.append 줬더니 None됨... 

니네 왜그래... 

+그거 해결봤음. 진짜 웃긴 과정이었음... 

handle2="/home/koreanraichu/sra_data_mo.fasta"
A = []
for record2 in SeqIO.parse(handle2,"fasta"):
    A.append(Seq(record2.seq).count("A"))
print(A)

애초에 만들었던 빈 리스트를 밖으로 빼니까 되는데요? 와 신박하네. 

handle2="/home/koreanraichu/sra_data_mo.fasta"
A = [] #아니 이게 이렇게 해결된다고?
T = []
G = []
C = []
for record2 in SeqIO.parse(handle2,"fasta"):
    A.append(Seq(record2.seq).count("A"))
    T.append(Seq(record2.seq).count("T"))
    G.append(Seq(record2.seq).count("G"))
    C.append(Seq(record2.seq).count("C"))
print("A: ",sum(A),"T: ",sum(T),"G: ",sum(G),"C: ",sum(C))

코드_최종.py

 

아니 진짜 저걸로 해결되는거면 판다스 표 개판 오분전 된것도 저걸로 걍 정리해버리자. 

 

3. 전체 Sequence 세기

print(sum(len(r) for r in SeqIO.parse(handle2, "fasta")))

와 이걸 이렇게 해결보네

 

4. Top 10 length

for record2 in SeqIO.parse(handle2,"fasta"):
    record_id=np.array(record2.id)
    record_len=np.array(len(record2.seq))
    record_table=pd.DataFrame({"ID":record_id, "length":record_len},index=[0])
    print(record_table)
    # Dataframe이 이상하게 생성된다.
    """
                   ID  length
    0  SRR000021.37.2     249
    이런 식으로 항목 하나당 한 데이터프레임이 생성되는데 Array까지는 정상적으로 생성됨. 
    """

판다스로 표 만들어서 꼽아보려고 했더니 표가 개판 오분전이 되었다... 이쯤되면 array 차원부터 한번 봐야겠는데? array 차원부터 망했는데 이거? 

# A4. Top 10 length
record_id=[] # 야 이걸 이렇게 해결보네
record_len=[]
for record2 in SeqIO.parse(handle2,"fasta"):
    record_id.append(record2.id)
    record_len.append(len(record2.seq))
record_id_array=np.array(record_id)
record_len_array=np.array(record_len)

비효율적으로 보일 지 몰라도 이정도면 본인 수준에서는 장족의 발전임다... 어레이 제대로 된 것도 확인했음. 

record_table=pd.DataFrame({"ID":record_id_array,"Length":record_len_array})
print(record_table)

아 표 ㄹㅇ 이쁘게 나왔음. 

 

                 ID  Length
0     SRR000021.1.2     176
1     SRR000021.1.4      49
2     SRR000021.2.2      99
3     SRR000021.2.4     106
4     SRR000021.3.2      64
..              ...     ...
102  SRR000021.52.2     269
103  SRR000021.52.4       0
104  SRR000021.53.2     276
105  SRR000021.54.2      65
106  SRR000021.54.4     184

캬... 이 표 이쁜거 보게. 근데 여기서 끝이 아니고 length를 또 봐야 한다... 살려주세요. 일단 전에 배웠던대로 오름차순 정렬을 해 보자. 

record_table2=record_table.sort_values('Length',ascending=0)
                 ID  Length
68   SRR000021.35.2     280
104  SRR000021.53.2     276
102  SRR000021.52.2     269
64   SRR000021.33.2     269
70   SRR000021.36.2     268
..              ...     ...
63   SRR000021.32.4       0
73   SRR000021.37.4       0
65   SRR000021.33.4       0
71   SRR000021.36.4       0
53   SRR000021.27.4       0

엥? 중복값이 있구나 이거. 

 

record_table2=record_table.groupby('Length').count()
record_table2=record_table2.sort_values('Length',ascending=0)
print(record_table2.head(10))
        ID
Length    
280      1
276      1
269      2
268      1
259      1
257      1
249      1
247      1
244      1
240      1

ID가 왜 저렇게 나오냐면 저거 그룹바이로 같은 값 묶어서 세달라고 카운트 걸어서 그렇다. 즉, 269에 2 있는 건 269bp가 두개라는 얘기. 그럼 아이디는 어떻게 뽑나요 쿼리 걸어 쿼리 

근데 생각해보니까 이거 빈도수 Top10이지 길이가 아니다. 

 

record_table2=record_table2.sort_values('ID',ascending=0)
        ID
Length    
0       15
107      3
63       3
99       3
44       2
105      2
111      2
178      2
64       2
124      2

이거 뭐 하는 데이터인데 0개가 이래 많음? 

 

5. 조건부 합계(여기서는 100bp 기준으로 나눴다)

for record2 in SeqIO.parse(handle2,"fasta"):
    if len(record2.seq) > 100:
        i=0
        i=i+len(record2.seq)
    else:
        j=0
        j=j+len(record2.seq)
print(i,j)

얘도 각개로 나온다. 일단 2번부터 해결해야 할 듯. 참고로 4번 코드를 보시면 아시겠지만, 넘파이 판다스 둘 다 불렀다. 

굳이 if 하지 말고 저거 해결 봤으니까 걍 위에 표 불러서 판다스 소환하자. 

 

print(record_table[record_table.Length >= 100].sum())
print(record_table[record_table.Length < 100].sum())
ID        SRR000021.1.2SRR000021.2.4SRR000021.3.4SRR0000...
Length                                                 9984
dtype: object
ID        SRR000021.1.4SRR000021.2.2SRR000021.3.2SRR0000...
Length                                                 1955
dtype: object

이거 셀렉터 못줌? 

print("length >= 100bp:",record_table['Length'][record_table.Length >= 100].sum())
print("length < 100bp:",record_table['Length'][record_table.Length < 100].sum())
length >= 100bp: 9984
length < 100bp: 1955

되는데요?