(실제 코드 결과로 작성, transcription factor binding site 데이터 이용)
- Dataframe에 새로운 column 작성하기
- Dataframe의 column split 후 다른 column으로 저장하기 # df[열이름].str.split() 이용
- Dataframe의 열 data를 split 후 다시 저장하기
- Pandas explode 메소드 사용하기 (데이터프레임 열에 리스트로 저장된 데이터에서 리스트 요소를 행으로 추가하기)
import pandas as pd
f1 = pd.read_csv('test.txt', delimiter = '\t', names = ['1', '2', '3', '4', '5', '6', '7', '8', '9'])
# 1~9로 열 이름 정해서 탭으로 분리된 파일 불러오기
위의 data를 보면 column name이 9인 열의 데이터가 합쳐져 있다.
한 줄의 data를 가져온 결과
binding_matrix_stable_id=ENSPFM0404;stable_id=ENSM00648832284;transcription_factor_complex=MYBL1::ONECUT2;epigenomes_with_experimental_evidence=GM12878%2CK562%2CHepG2%2CH1-hESC_3%2CHCT116
인데, 이 data를 각각 binding_matrix_stable_id, stable_id, transcription_factor_complex, epigenomes_with_experimental_evidence로 분리한 후 새로운 열로 지정하는 게 목표이다.
그런데 여기서 epigenomes_with_experimental_evidence는 없는 data도 상당히 많아서 ';'으로 분리한 결과의 길이에 따라 데이터프레임을 다시 만든 후 분리할 예정.
lst = f1['9'].str.split(';') # ;으로 분리 후 분리된 길이의 결과를 데이터프레임의 열로 추가
lst_len = lst.str.len()
f1['lst_len'] = lst_len
lst_len 열이 새로 생성된 것을 볼 수 있다.
이후 lst_len 이 3인 것과 4인 것으로 분리해 새로운 데이터프레임 생성.
# df1: len = 3인 경우
# df1: len = 4인 경우
df1 = f1[f1['lst_len'] == 3]
df2 = f1[f1['lst_len'] == 4]
# df1 column 분리 후 split
lst = df1['9'].str.split(';').str[0]
lst2 = df1['9'].str.split(';').str[1]
lst3 = df1['9'].str.split(';').str[2]
del df1['9']
df1['binding_matrix_stable_id'] = lst
df1['stable_id'] = lst2
df1['transcription_factor_complex'] = lst3
df1 column 분리 후 split 한 결과
내가 원하는 대로 column이 분리된 결과를 볼 수 있음 !!!
이제
binding_matrix_stable_id=ENSPFM0404
이런 식으로 생긴 data를 '=' 기준으로 분리할 것
lst = df1['binding_matrix_stable_id'].str.split('=').str[1]
lst2 = df1['stable_id'].str.split('=').str[1]
lst3 = df1['transcription_factor_complex'].str.split('=').str[1]
df1['binding_matrix_stable_id'] = lst
df1['stable_id'] = lst2
df1['transcription_factor_complex'] = lst3
역시나 내가 원하는 대로 딱 id, transcription_factor_complex 데이터로 잘 분리된 데이터프레임을 볼 수 있음.
이제 가장 문제였던(트롤,,,) transcription_factor_complex 열의 data를 split해서 행으로 추가할 것
transcription_factor_complex=CEBPE%2CGCM1::CEBPB%2CCEBPG%2CCEBPB%2CTEAD4::CEBPD%2CCEBPD
위 data를 보면 %와 ::을 경계로 모든 transcription_factor_complex가 합쳐져 있다. 이걸 분리해서 행으로 붙일 것이다.
complex_new = df1['transcription_factor_complex'].str.split('%') # %로 분리한 결과를 complex_new에 list로 저장
df1['transcription_factor_complex'] = complex_new # list로 저장한 결과를 열에 덮어씌우기
위처럼 list 형태로 transcription_factor_complex 열에 저장된 것을 볼 수 있다.
여기서 pandas explode를 이용해 작성한 함수로 column의 list 안의 것들을 행으로 추가할 것이다.
def unnest(df, tile, explode):
vals = df[explode].sum(1)
rs = [len(r) for r in vals]
a = np.repeat(df[tile].values, rs, axis=0)
b = np.concatenate(vals.values)
d = np.column_stack((a, b))
return pd.DataFrame(d, columns = tile + ['_'.join(explode)])
함수 선언 후
df1 = unnest(df1, ['1','2','3','4','5','6','7','8','binding_matrix_stable_id','stable_id'], ['transcription_factor_complex'])
# 기준이 되는 열을 2번째 인자로, 분리할 열을 3번째 인자로 호출
실행하면
%로 잘 분리되어 추가된 행을 볼 수 있다.
이제 위에 했던 방법처럼 '::'도 분리해 전처리 완성~!~!
:: 분리 과정은 위랑 똑같으니까 생략 ㅎㅎ
바이오 데이터라 개수가 엄청 많음...
Transcription Factor Binding Site 전처리 끝~