표의 내용을 믿거나 바꾸기 전에 구조와 맥락부터 확인하기
오늘의 학습 목표
- CSV 파일과 DataFrame 객체의 차이를 파일과 작업 공간의 관계로 설명할 수 있습니다.
- DataFrame에서 행, 열, 헤더, 인덱스, 셀을 가리킬 수 있습니다.
- 수치, 범주, 문자열, 날짜 자료형을 실제 열과 연결할 수 있습니다.
- 결측값과 숫자 0, 빈 문자열이 같은 뜻이 아님을 설명할 수 있습니다.
pd.read_csv(),head(),shape,columns,dtypes,isna().sum()의 출력을 읽을 수 있습니다.- 데이터의 출처·이용 조건·관찰 단위·기간과 답할 수 있는 질문을 한 장의 HTML 카드로 정리할 수 있습니다.
- 0-5분1교시 회상
관찰 단위와 변수를 행과 열에 연결합니다.
- 5-14분CSV 읽기
쉼표로 구분된 텍스트와 표의 관계를 봅니다.
- 14-25분DataFrame 해부
행, 열, 헤더, 인덱스, 셀을 구분합니다.
- 25-35분자료형과 결측값
값의 종류와 비어 있음의 의미를 판단합니다.
- 35-44분여섯 단계 점검
코드 출력으로 구조를 차례대로 확인합니다.
- 44-50분결과물 설계
3교시 데이터 읽기 카드의 계약을 확정합니다.
- 50-60분확장 진단
서로 다른 세 표의 문제를 개별 판단합니다.
수업 운영: 기본 50분과 확장 60분
기본 50분에는 CSV, DataFrame 구조, 자료형, 결측값, 여섯 단계 점검, 3교시 결과물 계약까지 진행합니다. 모든 확인이 빠르게 끝난 경우에만 50-60분 확장에서 구조가 다른 세 표를 진단합니다. 이번 시간에는 시각화와 통계 계산보다 데이터의 구조와 맥락 확인에 집중합니다.
0-5분 · 1교시의 언어를 표의 위치로 연결하기
1교시에는 “한 번의 창작 활동”을 관찰 단위로 정하고, 활동 종류·지속 시간·집중도처럼 매번 같은 기준으로 묻는 항목을 변수라고 했습니다. 표에서는 한 관찰 단위가 주로 한 행을 차지하고, 변수는 주로 한 열을 차지합니다. 실제 관찰에서 얻은 값은 행과 열이 만나는 셀에 들어갑니다.
오늘 계속 사용할 변환 문장
한 번의 관찰 → 한 행, 반복해서 묻는 항목 → 한 열, 실제로 기록된 내용 → 한 값
한 행과 한 열 가리키기
아래에 제공되는 DataFrame 도해에서 “2026-05-06의 한 행”과 “duration_min의 한 열”을 각각 찾습니다. 아직 코드를 읽지 않아도 됩니다.
확인: 한 행은 언제나 한 사람을 뜻하는가?
아닙니다. 한 행은 데이터셋이 정한 관찰 단위 하나를 뜻합니다. 사람 한 명일 수도 있고, 한 번의 활동, 한 작품, 한 날짜, 한 지역일 수도 있습니다. 따라서 표를 읽기 전에 관찰 단위를 먼저 확인해야 합니다.
5-14분 · CSV는 쉼표로 값을 구분한 텍스트 파일이다
CSV는 Comma-Separated Values의 약자로, 값을 쉼표로 구분해 저장하는 텍스트 파일 형식입니다. 스프레드시트처럼 칸이 보이는 화면이 파일 안에 저장되는 것이 아니라, 줄바꿈과 구분 기호로 표의 구조를 표현합니다.
record_id,date,activity,duration_min,focus_level
1,2026-05-04,sketch,35,3
2,2026-05-05,coding,55,4
3,2026-05-06,reading,25,2
| CSV에서 보이는 것 | 표에서의 의미 | 위 예시 |
|---|---|---|
| 첫 줄 | 열 이름을 적은 헤더 | record_id,date,... |
| 쉼표 | 한 줄 안의 값을 나누는 구분자 | 1과 2026-05-04 사이 |
| 줄바꿈 | 한 관찰과 다음 관찰을 나누는 경계 | 기록 1, 2, 3 |
| 빈 자리 | 기록되지 않은 값일 가능성 | ...,55,,coding |
CSV는 단순해서 여러 프로그램이 읽을 수 있지만, 파일 자체가 모든 의미를 설명하지는 않습니다. duration_min이 분 단위인지, focus_level의 범위가 1~5인지, 누가 언제 기록했는지는 별도의 메타데이터가 필요합니다.
CSV를 Excel에서 열면 Excel 파일이 되는가?
열어 보는 프로그램이 Excel일 뿐 원본 파일 형식은 여전히 CSV입니다. 여러 시트, 셀 색상, 수식 같은 Excel 전용 기능은 CSV에 보존되지 않습니다. 저장할 때 확장자와 형식을 확인해야 합니다.
값 안에 쉼표가 있으면 열이 잘못 나뉘는가?
표준 CSV에서는 쉼표가 포함된 값을 큰따옴표로 감쌀 수 있습니다. 예를 들어 "sketch, color study"는 하나의 값으로 읽힙니다. 수업에서는 pandas가 이 규칙을 처리하므로 임의로 문자열을 나누지 않습니다.
14-25분 · DataFrame은 Python 안의 2차원 표다
DataFrame은 pandas가 Python 안에서 다루는 2차원 표 형태의 객체입니다. CSV가 저장 공간에 있는 파일이라면 DataFrame은 그 파일을 읽어 현재 실행 중인 Python의 작업 공간에 펼쳐 놓은 표에 가깝습니다.
import pandas as pd
source_path = "week-09-creative-activity.csv"
df = pd.read_csv(source_path)
pd.read_csv(source_path)는 경로에 있는 CSV를 읽어 DataFrame을 만들고, 등호 왼쪽의 df가 그 객체를 가리키게 합니다. 이 코드는 원본 CSV의 내용을 바꾸지 않습니다. 파일을 읽어 메모리에 표 형태로 준비하는 단계입니다.
| 인덱스 | date | activity | duration_min | focus_level |
|---|---|---|---|---|
| 0 | 2026-05-04 | 스케치 | 35 | 3 |
| 1 | 2026-05-05 | 코딩 | 55 | 4 |
| 2 | 2026-05-06 | 읽기 | 25 | 2 |
| 3 | 2026-05-07 | 편집 | 70 | 5 |
| 4 | 2026-05-08 | 음악 | 40 | NA |
date문자열 또는 날짜activity범주 또는 문자열duration_min수치focus_level수치와 결측값
| 요소 | 역할 | 주의할 점 |
|---|---|---|
| 행 | 관찰 단위 하나의 기록 | 모든 행은 같은 변수 구조를 따라야 함 |
| 열 | 반복해서 기록한 변수 하나 | 한 열의 값은 가능한 한 같은 의미와 단위를 가져야 함 |
| 헤더 | 열의 이름 | 값이 아니라 구조를 설명하는 이름 |
| 인덱스 | DataFrame 안에서 행을 찾는 표지 | 원본의 record_id 열과 자동 인덱스는 별개일 수 있음 |
| 셀 | 행과 열이 만나는 한 칸 | 하나의 일관된 값 또는 결측값을 담음 |
확인: 인덱스 0과 record_id 1이 다른 이유는 무엇인가?
pandas는 CSV를 읽을 때 기본적으로 0부터 시작하는 인덱스를 새로 만듭니다. record_id는 원본 데이터에 이미 있던 식별 열입니다. 둘이 우연히 비슷해 보여도 역할이 다르므로 구분해서 읽습니다.
25-35분 · 자료형과 결측값은 값의 의미를 제한한다
컴퓨터는 모든 값을 같은 방식으로 다루지 않습니다. 더하거나 평균을 낼 수 있는 수치, 몇 가지 이름으로 분류하는 범주, 자유롭게 적은 문자열, 시간 순서를 가진 날짜는 서로 다른 연산을 요구합니다.
| 의미상 자료형 | 열 예시 | 값 예시 | 가능한 질문 |
|---|---|---|---|
| 수치 | duration_min, focus_level | 55, 4 | 가장 긴 활동은 무엇인가? |
| 범주 | activity, location_type | coding, school | 각 활동은 몇 번 기록되었는가? |
| 문자열 | note | fixed small bug | 어떤 메모가 남아 있는가? |
| 날짜 | date | 2026-05-05 | 기록 기간은 언제부터 언제까지인가? |
CSV에는 자료형 정보가 별도로 저장되지 않으므로 pandas가 값을 보고 자료형을 추론합니다. 날짜처럼 보이는 값이 처음에는 일반 문자열인 object로 읽힐 수 있고, 숫자 열에 빈 값이 있으면 정수 대신 실수형으로 읽힐 수 있습니다. dtypes는 “무엇으로 보여야 하는가?”가 아니라 “현재 pandas가 무엇으로 읽었는가?”를 보여 줍니다.
결측값은 숫자 0과 같지 않다
0은 측정 결과가 영이라는 실제 값입니다. 결측값은 기록하지 않았거나 알 수 없음을 뜻합니다. 집중도 0을 “집중하지 못함”으로 정의했다면 값이지만, 빈 셀은 그날 집중도를 기록하지 않았다는 뜻입니다. 이유를 모른 채 빈칸을 0으로 바꾸면 데이터의 의미가 달라집니다.
| 표현 | 가능한 뜻 | 바로 0으로 바꿔도 되는가? |
|---|---|---|
NaN 또는 NA | pandas가 인식한 결측값 | 아니요. 누락 이유와 변수의 의미를 먼저 확인 |
0 | 측정되거나 기록된 영 | 이미 하나의 값이므로 결측과 구분 |
"" | 길이가 0인 문자열 또는 빈 입력 | 파일을 읽는 설정에 따라 결측으로 처리될 수 있음 |
확인: focus_level이 float64이면 집중도는 소수로 측정했다는 뜻인가?
반드시 그렇지는 않습니다. 원래 1~5 정수 척도여도 결측값을 함께 표현하기 위해 pandas가 실수형으로 읽을 수 있습니다. 자료형 출력만 보지 말고 실제 값과 결측값의 존재를 함께 확인해야 합니다.
확인: 날짜가 object이면 잘못된 데이터인가?
데이터가 틀렸다는 뜻은 아닙니다. 현재 문자열처럼 읽혔다는 뜻입니다. 10주차에 필요하면 날짜형으로 변환하지만, 이번 주에는 값의 형식이 일관적인지와 기록 기간이 무엇인지 먼저 읽습니다.
35-44분 · 계산 전 여섯 단계로 구조 점검하기
처음 받은 데이터는 아래 순서로 점검합니다. pd.read_csv()로 불러오고, head(), shape, columns, dtypes, isna().sum()을 차례대로 봅니다. 한꺼번에 긴 출력 하나를 만드는 대신 각 질문에 맞는 작은 출력을 읽습니다.
import pandas as pd
df = pd.read_csv(source_path) # 1. 파일을 DataFrame으로 읽기
df.head() # 2. 앞부분의 값과 배치 보기
df.shape # 3. 행 수와 열 수 보기
df.columns.tolist() # 4. 정확한 열 이름 보기
df.dtypes # 5. pandas가 읽은 자료형 보기
df.isna().sum() # 6. 열마다 결측값 개수 보기
| 코드 | 읽는 질문 | 수업용 CSV의 예상 |
|---|---|---|
pd.read_csv() | 파일을 정상적으로 읽었는가? | df가 생성됨 |
head() | 첫 행들과 값의 형태는 어떠한가? | 기본 5행 |
shape | 행과 열은 각각 몇 개인가? | (24, 10) |
columns | 열 이름의 철자와 순서는 무엇인가? | 10개 이름 |
dtypes | 각 열을 현재 어떤 자료형으로 읽었는가? | 수치형과 object가 함께 있음 |
isna().sum() | 어느 열에 빈 값이 몇 개인가? | 일부 열에서 0보다 큼 |
shape의 결과는 항상 (행 수, 열 수) 순서입니다. (24, 10)은 24열이 아니라 24행과 10열입니다. 괄호가 함수 호출처럼 보여도 df.shape에는 뒤에 괄호를 붙이지 않습니다. shape, columns, dtypes는 현재 객체의 상태를 담은 속성이고, head()와 isna(), sum()은 실행하는 메서드입니다.
공식 문서에서 코드 읽는 법
pandas read_csv 공식 문서 ↗에는 매우 많은 선택 항목이 있습니다. 처음부터 전부 외우지 않습니다. 이번 주에는 첫 번째 입력인 파일 경로와 반환 결과가 DataFrame이라는 점만 확인합니다.
확인: head()에 문제가 없으면 전체 데이터도 문제없는가?
아닙니다. head()는 앞부분만 보여 줍니다. 파일이 올바르게 열렸는지 빠르게 확인하는 데 유용하지만, 뒤쪽의 결측값이나 형식 오류까지 보장하지 않습니다. 그래서 shape, dtypes, isna().sum()을 함께 봅니다.
오류: FileNotFoundError가 나오면 무엇부터 확인하는가?
코드를 바꾸기 전에 Colab 왼쪽 파일 패널에서 CSV가 실제로 업로드되었는지, 파일명의 대소문자·띄어쓰기·확장자가 source_path와 정확히 같은지 확인합니다. 오류는 데이터 내용이 아니라 경로를 찾지 못했다는 뜻입니다.
44-50분 · 3교시 고정 미션 계약
3교시의 결과물은 그래프가 아닙니다. 데이터를 바꾸거나 시각화하기 전에 무엇을 담고 있는지 설명하는 데이터 읽기 카드 HTML입니다. 노트북이 CSV를 읽고 카드 파일을 자동 생성하며, 학생은 데이터의 맥락과 질문, 실제 행·열·값의 의미를 자신의 문장으로 채웁니다.
| 제출물 | 보여 주는 것 | 파일명 |
|---|---|---|
| Colab 노트북 | CSV를 불러오고 구조를 검사한 실행 과정 | week09_학번_이름.ipynb |
| 데이터 읽기 카드 | 구조, 맥락, 질문, 한계를 정리한 독립 결과물 | week09_학번_이름_data_reading_card.html |
이번 주에 만들지 않는 것
평균 비교 그래프, 빈도 차트, 데이터 포스터는 아직 만들지 않습니다. 구조를 확인하지 않은 채 시각화하면 잘못 읽힌 자료형과 누락된 맥락을 그대로 확대할 수 있습니다. 10주차에 데이터를 정리하고, 11주차에 시각적 인코딩을 설계합니다.
확인: 카드의 “답할 수 없는 질문”은 실패를 적는 칸인가?
아닙니다. 현재 데이터의 범위를 정확히 이해했다는 증거입니다. 예를 들어 함께 작업한 사람이 누구인지 기록한 열이 없다면 “어떤 활동을 다른 사람과 함께했는가?”에는 답할 수 없습니다. 이를 밝히면 다음 수집에서 필요한 정보를 설계할 수 있습니다.
50-60분 · 확장: 구조가 다른 표 세 개 진단하기
기본 학습을 모두 마친 경우에만 개별로 진행합니다. 각 사례에서 관찰 단위, 구조 문제, 먼저 확인할 코드를 한 가지씩 적습니다.
| 사례 | 보이는 구조 | 진단 질문 |
|---|---|---|
| A · 활동 기록 | 24행, 10열, 일부 빈 집중도 | 빈 값은 어느 열에 몇 개인가? |
| B · 전시 방문 | 열 이름 두 개가 Unnamed, 날짜가 여러 형식 | 첫 줄이 정말 헤더인가? |
| C · 색상 조사 | 한 셀에 red/blue/yellow 세 값 | 한 셀의 값이 어떤 단위를 나타내는가? |
head()로 첫 행의 배치를 확인합니다.shape로 예상한 행·열 수와 맞는지 봅니다.columns로 이름이 빠지거나 밀리지 않았는지 봅니다.dtypes와isna().sum()으로 자료형과 빈 값을 확인합니다.- 지금 단계에서 알 수 없는 내용은 추측하지 않고 메타데이터 필요 항목으로 적습니다.
확장 활동의 완료 기준
세 사례 각각에 대해 “한 행이 무엇인지”, “가장 먼저 확인할 구조 문제”, “사용할 검사 코드”를 한 줄씩 적으면 완료입니다. 값을 직접 정리하는 작업은 10주차에 진행합니다.
수업 후 개별 복습
- CSV 파일과 DataFrame 객체의 차이를 “저장된 파일”과 “Python 안의 작업 표”라는 표현으로 설명합니다.
(24, 10)을 24행 10열로 읽습니다.- 인덱스와 원본의 식별자 열이 왜 다를 수 있는지 설명합니다.
- 결측값과 0을 바꾸어 쓰면 안 되는 이유를 예와 함께 적습니다.
- 여섯 단계 검사 코드를 파일 불러오기부터 결측값 확인까지 순서대로 적습니다.