부록 E06: pandas와 표 데이터
이 장에서 배울 것
이번 장에서는 판다스(pandas)와 표 데이터를 배웁니다. 판다스는 파이썬에서 표 형태 데이터를 다루는 대표적인 도구입니다. 유전자 발현량 표, 샘플 정보표, 임상 정보표, 차등발현 분석 결과표처럼 생물정보학 데이터는 표 형태가 매우 많습니다.
핵심 용어를 먼저 정리하겠습니다.
- 판다스(pandas): 파이썬에서 표 데이터를 다루는 라이브러리입니다.
- 데이터프레임(DataFrame): 판다스에서 표 전체를 나타내는 자료구조입니다. 영어 약어로
DataFrame또는df를 자주 씁니다. - 시리즈(Series): 데이터프레임의 한 열처럼 1차원 데이터를 나타냅니다.
- 행(row): 표에서 가로 한 줄입니다. 보통 샘플 하나나 유전자 하나를 나타냅니다.
- 열(column): 표에서 세로 한 줄입니다. 보통 변수 하나를 나타냅니다.
- 필터링(filtering): 조건에 맞는 행만 고르는 작업입니다.
- 그룹화(groupby): 같은 범주의 데이터끼리 묶어 계산하는 작업입니다.
- 병합(merge): 두 표를 공통 열 기준으로 합치는 작업입니다.
- 결측값(missing value): 값이 비어 있는 상태입니다.
가장 쉬운 비유: 엑셀을 코드로 다루기
판다스는 엑셀 표를 코드로 다루는 도구라고 생각하면 됩니다. 엑셀에서는 마우스로 열을 선택하고 필터를 걸지만, 판다스에서는 코드로 합니다.
import pandas as pd
df = pd.read_csv("expression.csv")
print(df.head())
여기서 pd는 pandas를 짧게 부르는 별명입니다. 생물정보학 코드에서 거의 관습처럼 쓰입니다.
CSV 파일 읽기
CSV 파일은 쉼표로 값을 구분한 표 파일입니다.
gene,expression,group
BRCA1,12.5,cancer
TP53,8.2,normal
EGFR,20.1,cancer
이 파일을 판다스로 읽으면 데이터프레임이 됩니다.
import pandas as pd
df = pd.read_csv("expression.csv")
앞부분 확인하기
파일을 읽은 뒤에는 먼저 앞부분을 확인합니다.
print(df.head())
head()는 표의 처음 몇 줄을 보여줍니다. 큰 파일을 다룰 때 전체를 출력하면 화면이 엉망이 되므로 head()가 유용합니다.
열 선택하기
특정 열만 보고 싶으면 대괄호를 씁니다.
print(df["gene"])
print(df["expression"])
여러 열을 고를 때는 리스트를 넣습니다.
print(df[["gene", "expression"]])
대괄호가 두 번 들어가는 것처럼 보여 헷갈릴 수 있습니다. 바깥 대괄호는 “데이터프레임에서 고르기”, 안쪽 리스트는 “고를 열 이름 목록”입니다.
조건으로 행 고르기
발현량이 10 이상인 행만 고르려면 이렇게 씁니다.
high = df[df["expression"] >= 10]
print(high)
안쪽 df["expression"] >= 10은 각 행이 조건을 만족하는지 참/거짓으로 표시합니다. 바깥 df[...]는 참인 행만 남깁니다.
정렬하기
발현량이 큰 순서로 정렬할 수 있습니다.
sorted_df = df.sort_values("expression", ascending=False)
print(sorted_df)
ascending=False는 큰 값부터 정렬하라는 뜻입니다.
새 열 만들기
기존 열을 이용해 새 열을 만들 수 있습니다.
df["is_high"] = df["expression"] >= 10
이제 is_high 열에는 각 유전자의 발현량이 10 이상인지 참/거짓이 들어갑니다.
그룹화해서 평균 계산하기
암 그룹과 정상 그룹의 평균 발현량을 비교하려면 그룹화를 쓸 수 있습니다.
mean_by_group = df.groupby("group")["expression"].mean()
print(mean_by_group)
뜻은 이렇습니다.
group열의 값으로 행을 묶습니다.- 각 그룹에서
expression열을 고릅니다. - 평균을 계산합니다.
결측값 확인하기
값이 비어 있으면 분석이 흔들릴 수 있습니다. 결측값을 확인하려면 다음을 씁니다.
print(df.isna().sum())
각 열에 비어 있는 값이 몇 개인지 보여줍니다.
두 표 병합하기
유전자 발현량 표와 유전자 설명 표를 합쳐야 할 때가 있습니다.
merged = pd.merge(expression_df, annotation_df, on="gene")
gene이라는 공통 열을 기준으로 두 표를 합칩니다.
저장하기
처리한 결과를 다시 CSV 파일로 저장할 수 있습니다.
high.to_csv("high_expression_genes.csv", index=False)
index=False는 판다스가 자동으로 붙이는 행 번호를 파일에 저장하지 않겠다는 뜻입니다.
생물정보학에서 왜 중요한가
RNA-seq 결과, 샘플 메타데이터, 변이 주석, 임상 정보는 대부분 표로 다룹니다. 판다스를 알면 이런 데이터를 필터링하고, 정렬하고, 그룹별로 요약하고, 다른 표와 합칠 수 있습니다. 생물정보학 분석의 상당 부분은 결국 표를 정확히 다루는 일입니다.
데이터 해석 관점: 표에서 질문을 코드로 바꾸기
판다스에서 가장 중요한 감각은 생물학 질문을 표 연산으로 바꾸는 것입니다. 예를 들어 질문이 “발현량이 10 이상인 유전자는 무엇인가?”라면 코드는 조건 필터링이 됩니다.
high = df[df["expression"] >= 10]
안쪽 df["expression"] >= 10은 각 행에 대해 참/거짓 목록을 만들고, 바깥 df[...]는 참인 행만 남깁니다.
그룹별 평균도 자주 씁니다.
df.groupby("group")["expression"].mean()
이 코드는 암 그룹과 정상 그룹처럼 같은 group 값을 가진 행을 묶은 뒤 expression 평균을 냅니다.
초보자가 자주 하는 실수는 행과 열을 헷갈리는 것입니다. 행은 보통 샘플이나 유전자 하나하나의 관측치이고, 열은 gene, group, expression 같은 변수입니다. 또 결측값을 무조건 지우면 샘플 수가 줄어 분석이 왜곡될 수 있습니다. 결측값은 먼저 왜 생겼는지 확인해야 합니다.
merge를 할 때는 공통 열이 정말 같은 ID 체계를 쓰는지도 확인해야 합니다. BRCA1과 brca1처럼 대소문자만 달라도 서로 다른 값으로 처리될 수 있습니다.
미니 실습 블록: pandas로 count matrix와 metadata 맞추기
이 실습은 pandas로 count matrix와 metadata 맞추기를 직접 손으로 확인하는 연습입니다. 왜 필요한가 하면, RNA-seq과 single-cell 분석에서 count matrix와 metadata가 어긋나면 조건 해석이 완전히 틀어질 수 있기 때문입니다.
import pandas as pd
counts = pd.read_csv("counts.csv", index_col=0)
meta = pd.read_csv("metadata.csv")
count_samples = set(counts.columns)
meta_samples = set(meta["sample_id"])
print("count에만 있음:", count_samples - meta_samples)
print("metadata에만 있음:", meta_samples - count_samples)
print(meta.isna().sum())
각 코드 요소의 의미를 풀어보면 다음과 같습니다. index_col=0은 첫 번째 열을 행 이름으로 사용합니다. set 차집합은 두 표의 sample_id 불일치를 찾는 데 유용합니다.
생물정보학/계산생물학에서 쓰이는 장면은 분명합니다. bulk RNA-seq count matrix와 metadata table을 DESeq2나 edgeR에 넣기 전 점검할 때 필요합니다.
흔한 오해 또는 주의점도 있습니다. sample_id mismatch를 무시하면 treated count에 control metadata가 붙거나 일부 샘플이 조용히 빠질 수 있습니다.
핵심 정리
판다스는 표 데이터를 다루는 파이썬 도구입니다. 데이터프레임은 표 전체, 행은 관측치, 열은 변수입니다. read_csv로 파일을 읽고, head로 확인하고, 조건 필터링으로 필요한 행을 고르며, groupby로 그룹별 계산을 할 수 있습니다.
문제 풀이
pandas와 표 데이터
주관식 답안은 Gemini API로 채점합니다. API 키는 이 브라우저에만 저장됩니다.
-
1. [쉬움] 객관식
판다스(pandas)의 설명으로 적절한 것은?
-
2. [쉬움] 객관식
데이터프레임(DataFrame)의 의미로 적절한 것은?
-
3. [코드] 객관식
pd.read_csv("expression.csv")의 역할은? -
4. [코드] 객관식
df.head()의 역할로 적절한 것은? -
5. [코드] 객관식
df["gene"]의 의미로 적절한 것은? -
6. [코드] 객관식
여러 열
gene,expression을 고르는 코드로 적절한 것은? -
7. [코드] 객관식
df[df["expression"] >= 10]의 의미로 적절한 것은? -
8. [코드] 객관식
sort_values("expression", ascending=False)의 의미로 적절한 것은? -
9. [코드] 객관식
df["is_high"] = df["expression"] >= 10의 의미는? -
10. [코드] 객관식
groupby("group")["expression"].mean()의 의미로 적절한 것은? -
11. [코드] 객관식
df.isna().sum()의 역할로 적절한 것은? -
12. [코드] 객관식
pd.merge(expression_df, annotation_df, on="gene")의 의미는? -
13. [보통] 객관식
to_csv("result.csv", index=False)에서index=False의 의미로 적절한 것은? -
14. [쉬움] 객관식
행(row)의 설명으로 적절한 것은?
-
15. [쉬움] 객관식
열(column)의 설명으로 적절한 것은?
-
16. [쉬움] 객관식
결측값(missing value)의 설명으로 적절한 것은?
-
17. [보통] 객관식
시리즈(Series)의 설명으로 적절한 것은?
-
18. [보통] 객관식
판다스가 생물정보학에서 중요한 이유는?
-
19. [계산] 객관식
다음 표에서
expression이 10 이상인 유전자는? BRCA1=12.5, TP53=8.2, EGFR=20.1 -
20. [코드] 객관식
group이 cancer인 행만 고르는 조건으로 적절한 것은? -
21. [중간] 객관식
표에서
expression >= 10을 만족하는 행만 남기려면 가장 적절한 코드는? -
22. [중간] 객관식
다음 표에서 cancer 그룹 expression 평균은? cancer 값: 12, 18 / normal 값: 4, 8
-
23. [중간] 객관식
df.groupby("group")["expression"].mean()의 의미로 맞는 것은? -
24. [중간] 객관식
df.isna().sum()이 알려주는 정보로 가장 적절한 것은? -
25. [중간] 객관식
pd.merge(expression_df, annotation_df, on="gene")에서on="gene"의 의미는? -
26. [중간] 객관식
to_csv("out.csv", index=False)에서index=False를 쓰는 이유로 맞는 것은? -
27. [중간] 객관식
다음 중 판다스 조건 필터링의 안쪽 표현
df["expression"] >= 10이 먼저 만드는 것은? -
28. [중간] 객관식
결측값을 무조건 삭제하면 위험한 이유는?
-
29. [실전] 객관식
pd.read_csv('counts.csv', index_col=0)에서index_col=0의 의미는? -
30. [실전] 객관식
count table에는
S3가 있고 metadata에는S3가 없다면 가장 큰 문제는? -
주관식 31. [실습] 주관식 · Gemini 채점
expression.csv를 읽고 앞부분을 출력하는 판다스 코드를 작성하라. -
주관식 32. [실습] 주관식 · Gemini 채점
데이터프레임
df에서gene열만 출력하는 코드를 작성하라. -
주관식 33. [실습] 주관식 · Gemini 채점
발현량이 10 이상인 행만 골라
high변수에 저장하는 코드를 작성하라. -
주관식 34. [실습] 주관식 · Gemini 채점
group별expression평균을 계산하는 코드를 작성하라. -
주관식 35. [실습] 주관식 · Gemini 채점
결측값 개수를 열별로 확인하는 코드를 작성하라.
-
주관식 36. [실습] 주관식 · Gemini 채점
판다스가 파일 입출력보다 편리한 점을 표 데이터 관점에서 설명하라.
-
주관식 37. [실습] 주관식 · Gemini 채점
작은 발현량 표에서 암 그룹과 정상 그룹의 평균을 비교하는 pandas 코드 흐름을 작성하라.
-
주관식 38. [실습] 주관식 · Gemini 채점
df[df["expression"] >= 10]가 내부적으로 어떤 두 단계로 동작하는지 설명하라. -
주관식 39. [실습] 주관식 · Gemini 채점
pandas로
metadata.tsv를 탭 구분자로 읽는 코드를 작성하라. -
주관식 40. [실습] 주관식 · Gemini 채점
count matrix 열 이름과 metadata의
sample_id를 set으로 비교해 서로 다른 ID를 출력하는 코드를 작성하라.