실제 데이터로 완성하는 나의 문화공간 목록
오늘의 학습 목표
- 공공데이터의 출처·수집 날짜·이용 조건을 확인하고 CSV를 내려받습니다.
- CSV의 헤더·쉼표·따옴표와 인코딩의 역할을 설명합니다.
- Colab에 CSV를 준비하고 셀 1의 준비 완료를 확인합니다.
- 0-5분이번 주말, 어느 문화공간에 가볼까?
- 5-10분파일보다 먼저 출처 페이지 읽기
- 10-18분공공데이터 CSV 직접 내려받기
- 18-32분CSV를 올리고 셀 1 준비 완료하기
- 32-41분CSV의 쉼표와 따옴표 읽기
- 41-47분어떤 열로 내 목록을 만들까?
- 47-50분준비 결과를 확인하고 2교시로 넘기기
교안과 노트북을 함께 보는 방법
노트북 하나를 세 교시 동안 이어서 사용합니다. 셀 번호는 제목의 번호이며 실행 버튼 옆의 실행 횟수와 다릅니다. 교안의 코드는 해당 셀의 설명입니다. 같은 코드를 새 셀에 덧붙이지 말고 번호가 같은 기존 셀을 실행하세요.
| 교시 | 노트북 위치 | 끝났을 때 보일 결과 |
|---|---|---|
| 1교시 | 셀 1 | 준비 완료와 입력 파일명 |
| 2교시 | 셀 2~7 | 전체 → 마포구 → 마포구 도서관 |
| 3교시 | 셀 8~11 | 나의 후보 → 새 CSV → 다시 읽기 → 검사 |
각 단원은 실행 절차 뒤에 개념 풀이, 실제 데이터 도해, 예상과 결과를 비교하는 연습이 이어집니다. 먼저 기존 셀의 결과를 확인하고, 설명을 읽으며 그 결과가 나온 이유를 짚어 보세요. 읽기용 예시 코드는 새 셀에 추가하지 않습니다.
0-5분 · 이번 주말, 어느 문화공간에 가볼까?
전시를 보고 싶거나 조용한 도서관을 찾을 때, 지도에서 장소를 하나씩 검색할 수 있습니다. 이미 정리된 시설 목록이 있다면 지역과 종류를 조건으로 한 번에 후보를 고를 수도 있습니다. 이번 주에는 공공기관이 공개한 목록을 가져와 자신만의 방문 후보 CSV를 만듭니다.
8주차에 기획한 데이터 프로젝트에서도 같은 순서가 필요합니다. 어디에서 파일을 얻는지, 한 행이 무엇인지, 어떤 열로 대상을 고를지 확인해야 합니다. 오늘은 모두 같은 문화공간 자료로 이 과정을 익힌 뒤, 자신의 기획에 적용할 수 있는 기술을 가져갑니다.
- 1교시 · 가져오기공공데이터 CSV출처에서 원본 파일 받기
- 2교시 · 공통 예제DataFrame마포구 → 도서관 순서로 선택하기
- 3교시 · 개인 적용나만의 CSV내 조건으로 선택하고 저장하기
나의 방문 목적 한 문장
“마포구에서 작업 후 들를 문화공간을 찾고 싶다”, “종로구의 도서관을 찾아보고 싶다”처럼 지역과 목적을 정합니다. 아직 시설 이름을 몰라도 됩니다. 마지막 교시에는 실제 목록에서 후보 하나를 고릅니다.
검색 결과를 보는 사람에서 목록을 만드는 사람으로
문화공간을 하나 검색하는 일과 문화공간 목록을 만드는 일은 목적이 다릅니다. 검색은 당장 방문할 한 곳의 자세한 정보를 찾기에 좋습니다. 목록은 같은 기준으로 여러 장소를 비교하거나, 다른 사람에게 전달하거나, 지도와 카드뉴스의 재료로 쓰기에 좋습니다. 이번 주에는 프로그램이 다룰 수 있는 목록을 직접 만듭니다.
예를 들어 “작업 후 들를 마포구의 도서관”이라는 생각에는 지역, 시설 종류, 방문 목적이 섞여 있습니다. 지역과 종류는 표의 값과 비교할 수 있습니다. “작업 후 들르기 좋다”는 판단에는 운영시간이나 이동 경로 같은 정보가 더 필요합니다. 프로그램으로 고르는 부분과 사람이 확인할 부분을 나누면 결과를 설명하기 쉬워집니다.
서울시 문화공간 정보
1,096개 시설 기록 · 26개 항목
어느 지역인가?
어떤 종류인가?
무슨 항목을 남길까?
방문 후보 CSV
시설명·주소를 담은 카드의 재료
다음 주 지도에 사용할 좌표
기억할 점 목록의 가치는 행을 많이 모으는 데만 있지 않습니다. 어떤 질문에 답하도록 골랐는지가 함께 드러나야 합니다.
생각해 보기 · 내 질문을 두 부분으로 나누기
먼저 예상: “친구와 이번 주말 갈 만한 종로구 문화공간”에서 표만으로 고를 수 있는 부분은 무엇일까요?
- 문장에서 지역에 해당하는 말을 찾습니다.
- 시설 종류를 제한할지, 여러 종류를 함께 볼지 정합니다.
- 실제 방문 전에 추가로 확인해야 할 정보 하나를 적습니다.
관찰할 것: 프로그램이 비교할 조건과 직접 확인할 방문 정보가 구분되어 있는지 봅니다.
다음 단계로 가기 전: 기존 셀의 값은 바꾸지 않습니다.
풀이와 확인 기준
자치구가 종로구인지 비교할 수 있습니다. 종류를 정하지 않았다면 전체로 두어 여러 종류를 볼 수 있습니다.
주말 운영 여부, 특정 전시 일정, 예약 가능 여부는 이 목록만으로 확정하지 않습니다. 후보를 고른 뒤 해당 시설에서 확인할 질문으로 남깁니다.
5-10분 · 파일보다 먼저 출처 페이지 읽기
공공데이터는 공공기관이 제공하는 데이터입니다. CSV는 그 자료를 전달하는 여러 파일 형식 중 하나입니다. CSV나 DataFrame은 설문 결과·매출 기록·개인 기록에도 쓰입니다. 이번 실습에서는 여러 사람이 같은 실제 자료를 확인할 수 있도록 공공데이터를 사용합니다.
사용할 자료는 서울열린데이터광장 「서울시 문화공간 정보」입니다. 시설명, 자치구, 종류, 주소와 좌표가 함께 있어 후보 목록을 만들고 다음 주의 지도 학습으로 이어가기 좋습니다.
| 항목 | 이 자료에서 확인한 내용 | 사용할 때의 의미 |
|---|---|---|
| 제공 기관 | 서울특별시 문화본부 문화정책과 | 자료의 출처를 노트북에 남깁니다. |
| 한 행의 대상 | 문화시설 기록 하나 | 행 수는 이 목록에 등록된 기록 수입니다. |
| 수집 기준일 | 수업 보관본: 2026-10-21 | 최신 파일과 행 수·내용이 달라질 수 있습니다. |
| 이용 조건 | 공공누리 제1유형 · 출처표시 | 제공 기관과 자료명, 링크를 표시합니다. |
업데이트 날짜를 읽는 방법
포털의 업데이트 날짜가 최근이어도 모든 시설의 운영시간과 관람료가 그날 확인되었다는 뜻은 아닙니다. 오늘 만드는 파일은 방문 후보 목록이고, 실제 방문 전 운영 정보는 시설 홈페이지에서 확인합니다.
목록의 1,096행을 “서울의 모든 문화공간”이라고 불러도 될까?
아닙니다. 1,096행은 수업 보관본에 들어 있는 기록 수입니다. 수집 대상이나 등록 기준에 따라 빠진 시설이 있을 수 있습니다. “이 데이터셋에 등록된 문화공간”이라고 표현합니다.
한 행의 단위가 질문의 범위를 정한다
이 자료의 한 행은 문화시설 기록 하나입니다. 도서관 한 곳이 여러 행사를 열더라도 그 행을 행사 한 번으로 세지 않습니다. 따라서 마포구에서 55행이 남았다는 결과는 “등록된 마포구 시설 기록 55개”입니다. “이번 달 마포구 행사 55개”라는 뜻으로 읽으면 기록의 단위를 바꾼 셈입니다.
데이터를 처음 열 때 열 이름보다 먼저 “한 행에 무엇 하나가 들어 있는가?”를 물어봅니다. 시설 목록, 공연 회차 목록, 방문객 설문은 모두 주소나 이름 열이 있을 수 있지만 한 행이 뜻하는 대상은 다릅니다. 단위가 다르면 행 수를 세어 얻는 결론도 달라집니다.
| 자료의 종류 | 한 행 | 행 수를 세면 알 수 있는 것 |
|---|---|---|
| 이번 문화공간 자료 | 문화시설 기록 하나 | 목록에 등록된 시설 기록 수 |
| 공연 일정 자료의 예 | 공연의 특정 회차 하나 | 등록된 공연 회차 수 |
| 방문 설문 자료의 예 | 응답 하나 | 응답 기록 수 · 실제 방문객 전체 수와 구분 |
기억할 점 행 수를 설명할 때 “무엇의 수인지”를 붙여 말합니다.
포털, 제공 기관, 원본 시스템을 구분하기
서울열린데이터광장은 파일을 찾아 내려받는 공개 창구입니다. 이 자료의 제공 부서는 서울특별시 문화본부 문화정책과이고, 원본 시스템은 서울문화포털입니다. 자료가 실린 웹사이트와 내용을 관리하는 주체가 항상 같은 이름으로 보이지는 않습니다. 출처를 기록할 때 포털 이름만 쓰기보다 자료명과 제공 기관을 함께 적습니다.
수집 날짜는 내가 이 버전의 파일을 확보한 날입니다. 시설의 개관일, 개별 값이 수정된 날, 웹페이지의 갱신 표시와 구분합니다. 같은 링크에서 내일 받은 파일은 오늘 파일과 행 수나 값이 달라질 수 있으므로, 실습 결과를 다시 확인하려면 링크와 함께 사용한 파일을 보관해야 합니다.
출처 메모 예시 · 직접 받은 파일은 자신의 수집 날짜와 버전을 적습니다.
자료명: 서울시 문화공간 정보
제공 기관: 서울특별시 문화본부 문화정책과
공개 창구: 서울열린데이터광장
자료 링크: https://data.seoul.go.kr/dataList/OA-15487/S/1/datasetView.do
수집 날짜: 2026-10-21
사용 버전: 수업 보관본
이용 조건: 공공누리 제1유형 · 출처표시기억할 점 다른 사람이 같은 입력을 찾을 수 있도록 자료명·기관·링크·수집 날짜·사용 버전을 남깁니다.
판단 연습 · 같은 파일을 쓰고 있는가?
먼저 예상: 두 학생의 행 수가 다른데 모두 같은 자료 링크를 적었다면 누가 잘못한 것일까요?
- 두 사람이 내려받은 날짜를 비교합니다.
- 둘 다 검색 조건을 비우고 전체 CSV를 받았는지 확인합니다.
- 직접 받은 최신 파일인지 수업 보관본인지 확인합니다.
관찰할 것: 행 수를 고치기 전에 입력 파일의 버전과 다운로드 범위를 비교합니다.
다음 단계로 가기 전: 기존 셀의 값은 바꾸지 않습니다.
풀이와 확인 기준
링크가 같다는 사실만으로 파일의 내용이 같다고 판단할 수 없습니다. 날짜나 검색 범위가 달라졌을 수 있습니다.
각자의 입력에 올바른 선택을 적용했는지가 판단 기준입니다. 수업 예시와 숫자를 맞추기 위해 기록을 임의로 지우지 않습니다.
10-18분 · 공공데이터 CSV 직접 내려받기
자료를 가져오는 방법에는 파일 다운로드와 API 요청 등이 있습니다. 파일 다운로드는 공개된 파일을 저장하는 방법이고, API는 코드로 서버에 요청해 응답을 받는 방법입니다. 이번 주에는 CSV 파일 다운로드를 사용합니다. API 인증키 발급은 필수 과정에 포함하지 않습니다.
- 서울시 문화공간 정보 페이지를 엽니다.
- 자료명·제공 기관·이용 조건을 확인하고, 데이터 영역의 Sheet 탭을 찾습니다.
- 시설명 검색 조건은 비워 두고 내려받기(CSV)를 누릅니다. JSON 버튼과 구분합니다.
- 다운로드 폴더에서
서울시 문화공간 정보.csv를 찾습니다. 중복 다운로드로(1)이 붙었으면 실제 이름을 기억합니다. - 수업 폴더에 원본을 보관하고, 자료 링크와 내려받은 날짜를 메모합니다.
포털 접속이 안 될 때
수업 보관본 CSV 내려받기 · 약 1.5 MB. 2026-10-21 포털에서 받은 원본 그대로이며 가상 데이터가 아닙니다. 출처와 수집 정보도 확인할 수 있습니다. 직접 받은 파일과 보관본 중 하나를 사용하면 됩니다.
파일을 가져왔다고 확인할 수 있는 증거
파일 확장자가 .csv인지 확인하고, 파일명·출처 링크·수집 날짜를 메모합니다. 브라우저의 데이터 미리보기 화면을 보는 것과 내 컴퓨터에 파일을 저장한 것을 구분합니다.
CSV를 더블클릭했는데 Excel이 열리면 Excel 파일인가?
CSV를 열도록 연결된 앱이 Excel일 뿐입니다. CSV 자체는 텍스트 파일입니다. 여러 시트·셀 색상·수식을 보관하는 Excel 통합 문서(.xlsx)와는 다릅니다.
CSV는 형식이고 다운로드는 가져오는 방법이다
CSV, Excel, JSON은 자료를 표현하거나 저장하는 방식입니다. 다운로드와 API 요청은 자료를 가져오는 방법입니다. 서로 다른 분류이므로 “CSV 대신 API를 쓴다”는 말만으로 결과의 모양을 알 수 없습니다. API가 JSON을 돌려줄 수도 있고 CSV 파일을 제공하는 주소가 있을 수도 있습니다.
지금 필요한 것은 행과 열이 이미 정리된 시설 목록입니다. 공개된 CSV를 받으면 별도 인증키나 응답 구조를 다루기 전에 표 읽기와 선택에 집중할 수 있습니다. 이후 주기적으로 최신 자료를 받아야 하는 프로젝트에서는 요청 방법과 갱신 주기를 따로 설계할 수 있습니다.
| 형식 | 기본 구조 | 이번 실습과 연결 |
|---|---|---|
| CSV | 구분자와 따옴표 규칙을 가진 텍스트 | read_csv로 읽고 to_csv로 저장 |
| XLSX | 시트·셀 서식 등을 담는 Excel 통합 문서 | CSV와 다른 읽기 함수와 시트 선택이 필요 |
| JSON | 객체·배열 등이 중첩될 수 있는 텍스트 | 어느 배열이 기록 목록인지 확인한 뒤 표로 변환 |
| API 응답 | 요청에 따라 서버가 보내는 데이터 | 응답의 형식과 구조를 별도로 확인 |
기억할 점 이번에는 “공개 포털에서 CSV 파일을 내려받아 pandas로 읽는다”라고 작업을 정확히 표현합니다.
파일 이름과 내용은 서로 다른 증거다
파일 이름은 원하는 자료를 찾는 단서지만 내용의 형식을 보증하지는 않습니다. 예를 들어 CSV 다운로드 대신 웹페이지 저장을 하면 HTML 문서가 생길 수 있습니다. 확장자 글자만 .csv로 바꾼다고 표 데이터로 변환되지 않습니다. 다운로드한 대상이 맞는지 파일명과 크기, 다음 교시의 첫 출력으로 함께 확인합니다.
중복 다운로드 때문에 파일명 끝에 (1)이 붙는 것은 흔한 일입니다. 이 경우 파일 내용이 다른지와 파일 이름이 다른지를 나누어 생각합니다. Colab에서 읽으려면 실제 이름을 정확히 사용해야 하지만, 이름에 (1)이 붙었다는 이유만으로 데이터가 틀렸다고 판단하지 않습니다.
서버의 파일 → 내 컴퓨터
CSV 바이트를 확보
내 컴퓨터 → Colab
실행 환경이 파일에 접근
CSV → DataFrame
헤더와 값의 경계를 해석
기억할 점 파일을 받았다는 확인과 내용을 제대로 읽었다는 확인을 각각 수행합니다.
18-32분 · CSV를 올리고 셀 1 준비 완료하기
파일을 받았으면 바로 Colab에 올립니다. 내 컴퓨터의 CSV와 Colab의 파일은 별개입니다. 아래 노트북을 한 번 열고 세 교시 동안 계속 사용합니다.
- 9주차 실습 노트북을 내려받아 Google Colab의 파일 → 노트북 업로드로 엽니다.
- Colab 왼쪽 파일 패널의 업로드로 원본 CSV를 올립니다. 이때 올리는 것은
.ipynb가 아닌.csv입니다. - 노트북에서 셀 1 · 입력 파일 준비를 찾고 아래 입력 항목을 채웁니다.
- 셀 1의 실행 버튼을 누릅니다. 출력의 준비 완료와 파일명이 맞는지 확인합니다.
| 항목 | 직접 받은 CSV 사용 | 포털 이용이 어려울 때 |
|---|---|---|
| student_id · student_name | 학번 · 이름 | 학번 · 이름 |
| source_mode | upload 유지 | snapshot 선택 |
| upload_filename | 파일 패널에 보이는 정확한 이름 | 바꾸지 않아도 됩니다. |
| acquired_on | 실제 내려받은 날짜 · 예: 2026-10-21 | 보관본 날짜가 자동으로 적용됩니다. |
| source_encoding | 원본은 cp949 유지 | cp949 유지 |
노트북 셀 1 · 입력 파일 준비
수정할 것: 학번·이름, 입력 방식, 업로드 파일명과 수집 날짜를 입력합니다.
성공 확인: 준비 완료와 사용할 파일명이 표시됩니다.
준비 셀은 제공 코드입니다
학번·입력 항목만 수정합니다. 파일 복구와 준비 코드는 교수자가 제공하므로 그대로 실행하면 됩니다. 1교시에는 셀 1까지만 실행합니다. 파일을 표로 읽는 과정은 2교시에 함께 시작합니다.
파일을 찾을 수 없다고 나오면?
왼쪽 파일 패널에 CSV가 있는지 확인합니다. 파일명에 공백이나 (1)이 붙었으면 upload_filename에도 똑같이 적습니다. 포털 이용이 어려워 보관본 모드를 선택했다면 따로 업로드할 필요 없이 셀 1이 원본을 복구합니다.
준비 셀의 입력과 제공 코드 구분
파일을 읽는 수업을 시작하기 전에 실행 환경이 사용할 대상을 정합니다. 이 셀에는 학습자가 입력할 항목과 파일을 준비하는 제공 코드가 함께 있습니다. 입력값이 어느 역할인지 알면 긴 준비 코드를 외우지 않아도 필요한 부분을 고칠 수 있습니다.
| 표현 | 하는 일 | 출력 또는 다음 단계 |
|---|---|---|
student_id / student_name | 결과 파일에 들어갈 작성자 정보 | 나중에 셀 9의 파일명에 사용됩니다. |
source_mode = "upload" | 업로드한 CSV를 사용한다는 선택 | 파일 패널의 파일명과 upload_filename이 같아야 합니다. |
source_mode = "snapshot" | 수업 보관본을 복구한다는 선택 | 2026-10-21 원본 파일이 Colab에 준비됩니다. |
source_path | 실제로 읽을 파일의 위치 | 셀 2가 이 값을 받아 read_csv에 전달합니다. |
source_encoding | 바이트를 문자로 읽을 규칙 | 확인한 원본은 cp949입니다. |
기억할 점 셀 1은 데이터 내용을 바꾸는 단계가 아니라, 이후 코드가 같은 입력을 찾게 하는 단계입니다.
내 컴퓨터, 노트북 문서, 런타임의 세 위치
Colab은 브라우저에서 보지만 Python 코드는 연결된 런타임에서 실행됩니다. 내 컴퓨터 다운로드 폴더에 CSV가 있어도 런타임이 그 폴더를 자동으로 읽지는 않습니다. 파일 패널에 올리는 과정은 코드를 실행할 컴퓨터가 사용할 입력을 전달하는 일입니다.
.ipynb는 코드·설명·저장된 출력이 들어 있는 노트북 문서입니다. .csv는 코드가 읽을 데이터 파일입니다. 노트북 업로드 메뉴와 왼쪽 파일 패널 업로드는 같은 일을 두 번 하는 것이 아닙니다. 첫 번째는 실행할 문서를 여는 일이고, 두 번째는 그 문서의 코드가 사용할 입력을 준비하는 일입니다.
런타임이 초기화되면 Python 변수와 임시로 올린 파일을 다시 준비해야 할 수 있습니다. 화면에 과거 실행 결과가 남아 있어도 현재 런타임에 df가 존재한다는 뜻은 아닙니다. 이때는 출력의 모양만 믿지 말고 같은 원본을 준비한 뒤 셀 1부터 순서대로 실행합니다.
원본 CSV 보관
다운로드한 실습 노트북
마지막에 받을 결과 CSV
11개 코드 셀
각 셀의 설명과 실행 출력
학번·이름·조건·선택 이유
업로드한 원본 CSV
실행 중 만들어질 df와 selected
to_csv가 기록할 결과 파일
기억할 점 입력 파일과 코드가 같은 실행 환경에서 만나야 다음 단계가 진행됩니다.
파일 오류를 고칠 때는 한 곳에서 경로를 정한다
이번 노트북은 셀 1에서 파일명과 인코딩을 정하고 뒤의 셀들이 그 값을 사용하도록 구성되어 있습니다. 셀 2에서 별도의 파일명을 다시 적으면 셀 1이 준비한 파일과 실제로 읽는 파일이 달라질 수 있습니다. 오류가 생겼을 때 입력 위치를 한 곳으로 모으면 수정할 지점이 분명해집니다.
파일 패널에는 원본이 있는데 찾지 못한다면 파일명 전체를 비교합니다. 한글, 띄어쓰기, 괄호, .csv까지 일치해야 합니다. “내 컴퓨터에는 있다”와 “Colab 파일 패널에 있다”를 구분한 뒤 upload_filename을 고칩니다. 같은 원본이 준비되어 있다면 파일을 반복해서 새로 받을 필요는 없습니다.
| 보이는 상황 | 먼저 확인 | 다음 행동 |
|---|---|---|
| 파일 패널이 비어 있음 | CSV를 런타임에 올렸는가 | 원본 업로드 → 셀 1 |
| 파일은 있으나 이름이 다름 | 공백·(1)·확장자 | 셀 1의 upload_filename 수정 → 셀 1 |
| 출력은 남았지만 변수 오류 | 런타임이 새로 시작되었는가 | 원본 준비 → 셀 1부터 실행 |
| 포털에서 파일을 받을 수 없음 | 수업 보관본 사용 여부 | source_mode를 snapshot으로 설정 → 셀 1 |
기억할 점 파일을 바꾸기 전에 파일의 위치와 코드가 사용하는 이름을 먼저 맞춥니다.
32-41분 · CSV의 쉼표와 따옴표 읽기
CSV는 보통 쉼표로 필드를 구분하는 텍스트 파일입니다. 첫 레코드의 열 이름을 헤더라고 합니다. 아래는 원본에서 3개 열과 2개 기록을 골라 보여 주는 설명용 발췌입니다. 전체 원본에는 26개 열이 있습니다.
"문화시설명","자치구","버스정거장"
"DDP(동대문디자인플라자)","중구","동대문역사문화공원, 광희동, 을지로 6가 국립중앙의료원"
"우란2경","성동구",""DDP의 버스정거장 값 안에도 쉼표가 있습니다. 큰따옴표는 이 쉼표까지 하나의 값에 포함된다는 경계를 표시합니다. 값에 줄바꿈이 들어가면 한 레코드가 화면의 여러 줄에 걸쳐 보일 수도 있습니다. 단순히 쉼표나 줄바꿈으로 문자열을 자르는 것으로 CSV를 정확히 읽을 수 없는 이유입니다.
이 구조를 해석해 값과 열을 구분하는 일을 파싱(parsing)이라고 합니다. 다음 교시의 pd.read_csv()가 CSV 규칙을 해석해 표를 만들어 줍니다. 이미 CSV로 받은 자료는 CSV를 파싱하여 DataFrame으로 읽고, 원하는 결과는 다시 CSV로 저장합니다.
위의 DDP 기록은 쉼표가 많으니 열도 더 많을까?
아닙니다. 헤더와 마찬가지로 3개 열입니다. 따옴표 안의 쉼표는 “버스정거장”이라는 한 값에 포함됩니다.
한글이 깨져 보이면 데이터가 없는 것일까?
한글을 바이트로 저장하고 읽는 규칙인 인코딩이 맞지 않을 수 있습니다. 확인한 원본은 CP949입니다. 2교시에서 encoding="cp949"를 지정해 읽습니다. 잘못 보이는 상태로 덮어쓰지 말고 원본을 보관합니다.
텍스트의 구분자가 표의 칸이 되는 과정
CSV를 텍스트로 보면 줄과 쉼표가 보이고, 표로 열면 행과 열이 보입니다. 서로 다른 데이터가 아니라 같은 기록을 다른 방식으로 표현한 것입니다. 파서는 “따옴표로 감싼 값 안인가, 값과 값의 경계인가?”를 구분하여 각 값을 열에 배치합니다.
앞의 DDP 발췌에서 버스정거장에 포함된 쉼표까지 모두 열의 경계로 처리하면 헤더보다 값이 많아집니다. 그래서 문자열을 단순히 split(",")으로 자르는 코드는 일반적인 CSV 읽기를 대신할 수 없습니다. 이번 실습에서는 이 규칙을 처리하는 read_csv를 사용하고, 우리는 결과가 의도한 열로 나뉘었는지 확인합니다.
| 인덱스 | 문화시설명 | 자치구 | 버스정거장 |
|---|---|---|---|
| 0 | DDP(동대문디자인플라자) | 중구 | 동대문역사문화공원, 광희동, 을지로 6가 국립중앙의료원 |
| 1 | 우란2경 | 성동구 | 빈 값 |
기억할 점 값 안의 쉼표는 그대로 남고, 값 사이의 쉼표는 열 경계로 해석됩니다.
헤더, 레코드, 값은 서로 다른 단위다
헤더는 각 항목의 이름을 정하는 첫 레코드입니다. 문화시설명이라는 글자는 첫 시설의 이름이 아니라 이후 값이 어떤 종류인지 알려 주는 열 이름입니다. 일반적인 이번 읽기에서는 헤더가 데이터 행 수에 포함되지 않습니다. 따라서 1,096행이라는 출력은 헤더 아래의 시설 기록 수를 뜻합니다.
화면에 보이는 줄 수와 레코드 수도 항상 같지는 않습니다. 시설소개 같은 긴 값 안에 줄바꿈이 들어갈 수 있기 때문입니다. 따옴표 안의 줄바꿈은 한 값의 일부일 수 있습니다. 텍스트 편집기에서 줄 번호만 세어 데이터 행 수라고 부르면 틀릴 수 있고, 파싱한 표의 shape로 확인해야 합니다.
저장 장치의 숫자열
한글도 바이트로 기록되어 있음
encoding으로 읽는 규칙 지정
한글·쉼표·따옴표를 얻음
CSV 규칙으로 값의 경계 구분
헤더와 데이터 행을 얻음
기억할 점 문자를 제대로 읽는 문제와 문자를 올바른 열에 배치하는 문제를 구분합니다.
한글이 깨지는 이유를 바이트로 이해하기
인코딩은 문자를 바이트로 표현하는 규칙입니다. 같은 “가”도 CP949에서는 16진수 바이트 b0 a1, UTF-8에서는 ea b0 80으로 표현됩니다. 이 숫자를 외울 필요는 없습니다. 같은 글자라도 저장 규칙에 따라 파일 안의 바이트가 달라진다는 점을 이해하면 됩니다.
원본이 CP949인데 UTF-8 규칙으로 해석하려 하면 오류가 나거나 기대한 문자를 얻지 못할 수 있습니다. encoding 인자는 깨진 글자를 예쁘게 표시하는 옵션이 아니라 처음부터 어떤 규칙으로 읽을지 정하는 입력입니다. 원본을 다시 저장하기 전에 올바른 규칙으로 읽는 것으로 문제가 해결되는지 확인합니다.
3교시에서는 읽어 둔 문자를 UTF-8-SIG 규칙으로 새 파일에 씁니다. 입력 파일의 인코딩과 출력 파일의 인코딩이 달라도, 올바르게 읽고 저장하면 같은 시설명을 전달할 수 있습니다. 이때 변경되는 것은 새 파일의 바이트 표현이고, 원본 파일은 그대로 보관합니다.
| 증상 | 가능한 원인 | 확인할 곳 |
|---|---|---|
| 파일을 찾을 수 없음 | 위치나 이름 불일치 | 셀 1 파일명과 파일 패널 |
| UnicodeDecodeError | 문자 해석 규칙 불일치 | 원본의 인코딩과 source_encoding |
| 예상한 열 이름이 없음 | 다른 자료·다른 형식·열 구조 변경 | 받은 파일과 다음 교시의 columns 출력 |
| 한 시설의 긴 설명이 여러 줄 | 값 안의 줄바꿈 | CSV 파싱 후 실제 행과 값 |
기억할 점 오류의 종류를 보고 파일 위치, 문자 규칙, 표 구조 중 어디를 확인할지 정합니다.
구조 읽기 · 빈 문자열도 한 칸일까?
먼저 예상: 앞의 우란2경 기록 끝에 있는 ""를 지워도 같은 구조일까요?
- 헤더에서 버스정거장이 몇 번째 열인지 찾습니다.
- 우란2경의 문화시설명·자치구·버스정거장 값을 각각 말합니다.
- 버스정거장이 빈 값이라는 사실과 그 열이 없다는 상황을 구분합니다.
관찰할 것: 값이 없어도 해당 항목의 자리는 유지된다는 점을 확인합니다.
다음 단계로 가기 전: 기존 셀의 값은 바꾸지 않습니다.
풀이와 확인 기준
우란2경의 버스정거장 값은 비어 있습니다. 문화시설명과 자치구만 가진 별도 두 열 구조라는 뜻은 아닙니다.
빈 필드는 파서에서 결측값으로 읽힐 수 있습니다. 정거장이 없다는 단정과 정보가 기록되지 않았다는 해석은 다르므로 원본의 의미를 확인합니다.
41-47분 · 어떤 열로 내 목록을 만들까?
한 행은 시설 기록 하나, 한 열은 모든 시설에 반복되는 항목입니다. 셀은 특정 행과 열이 만나는 값 하나입니다. 시설명을 보면 대상을 알 수 있고, 자치구와 주제분류를 보면 조건을 만들 수 있습니다.
| 열 | 역할 | 예 또는 주의점 |
|---|---|---|
| 번호 | 원본 기록과 대조 | 원본에 들어 있는 값이며 pandas 인덱스와 다릅니다. |
| 문화시설명 | 후보의 이름 | DDP(동대문디자인플라자) |
| 주제분류 | 종류 선택 | 공연장, 도서관, 미술관/갤러리 등 |
| 자치구 | 지역 선택 | 마포구, 중구 등 |
| 주소 | 장소 확인 | 서울특별시 중구 을지로 281 |
| 무료구분 | 원본의 비용 분류 | 무료 / 유료. 프로그램별 비용까지 보장하지 않습니다. |
| 위도 · 경도 | 다음 주 지도에 쓸 좌표 | 숫자로 읽히는지, 유효한지 다음 주에 검사합니다. |
질문을 열 이름으로 바꾸기
“종로구에서 도서관을 찾는다”에 필요한 조건 열 두 개를 적습니다. 후보의 이름과 위치를 보여 주려면 어떤 열을 더 남겨야 하는지도 적습니다.
“오늘 저녁에 여는 무료 전시”를 이 표만으로 확정할 수 있을까?
자치구와 무료구분으로 후보는 고를 수 있습니다. 하지만 시설 분류와 개별 행사 일정은 다릅니다. 운영시간이 비어 있거나 최신이 아닐 수도 있으므로 확정하려면 행사·시설의 최신 운영 정보가 추가로 필요합니다.
열을 고를 때는 세 가지 역할을 나눈다
조건 열은 어떤 기록을 남길지 결정합니다. 자치구와 주제분류가 여기에 해당합니다. 표시 열은 선택한 기록을 사람이 알아보게 합니다. 문화시설명과 주소가 대표적입니다. 추적과 다음 작업을 위한 열도 있습니다. 번호는 원본과 대조할 때, 위도·경도는 다음 지도 학습에서 사용합니다.
조건에 사용하지 않는 열도 결과에 필요할 수 있습니다. 자치구가 마포구인지 골랐다고 자치구 열을 반드시 지워야 하는 것은 아닙니다. 결과를 받은 사람이 어떤 지역의 자료인지 확인하도록 남길 수 있습니다. 반대로 26개 항목을 모두 가져오면 긴 소개·이미지 주소 때문에 후보를 비교하기 어려울 수 있어 목적에 맞는 8개를 선택합니다.
자치구 = 마포구
주제분류 = 도서관
문화시설명 · 주소
무료구분과 분류를 참고
번호로 원본 대조
위도·경도로 지도 학습 준비
기억할 점 남기는 열마다 “이 열이 있어야 하는 이유”를 한 문장으로 말해 봅니다.
값의 모양만 보고 의미를 정하지 않기
번호와 위도는 모두 숫자처럼 보이지만 역할이 다릅니다. 번호는 기록을 가리키는 값이고, 위도는 위치를 나타내는 값입니다. 번호를 평균 내는 것은 방문 후보를 찾는 데 의미가 없으며, 좌표는 숫자로 계산하기 전에 형식과 범위를 확인해야 합니다.
빈 값도 곧바로 0으로 읽지 않습니다. 관람료가 비었다는 것은 정보가 기록되지 않았다는 뜻일 수 있고, 무료라는 뜻은 아닙니다. 무료구분에 무료라고 적혀 있어도 시설의 모든 프로그램이 무료라는 결론까지 확장하지 않습니다. 한 칸의 의미는 열 설명과 수집 맥락을 함께 보아야 합니다.
열 선택 연습 · 세 질문을 구분하기
먼저 예상: 다음 중 이번 표의 열로 바로 조건을 만들 수 있는 질문은 무엇인가요?
- “은평구에 등록된 도서관”에 대응하는 열과 값을 적습니다.
- “지금 사람이 적은 도서관”에 필요한데 없는 정보를 적습니다.
- “지도에 표시할 시설 후보”에서 추가로 남길 열을 적습니다.
관찰할 것: 존재하는 열을 사용한 조건과 새로 확보해야 할 정보를 구분합니다.
다음 단계로 가기 전: 기존 셀의 값은 바꾸지 않습니다.
풀이와 확인 기준
첫 질문은 자치구 = 은평구, 주제분류 = 도서관으로 표현할 수 있습니다.
실시간 혼잡도는 이 표에서 바로 확인할 수 없습니다. 지도에는 위도·경도가 필요하지만 값을 검증하는 단계가 먼저 필요합니다.
기억할 점 없는 정보를 추측해 채우기보다 질문의 범위와 추가로 필요한 자료를 명확히 합니다.
47-50분 · 준비 결과를 확인하고 2교시로 넘기기
노트북으로 돌아가 셀 1 아래의 파일명을 확인합니다. 원본 CSV를 보관했고, 출처와 수집 날짜를 기록했으며, 준비 완료가 보이면 1교시를 마쳤습니다.
다음 교시의 시작점
같은 노트북의 셀 2부터 시작합니다. 파일을 다시 내려받거나 새 노트북을 만들지 않습니다. 쉬는 동안 런타임이 초기화되었다면 같은 원본을 준비해 셀 1을 다시 실행합니다.
설명하며 마무리 · 다음 사람에게 파일 넘기기
먼저 예상: 친구가 내 파일로 같은 실습을 시작하려면 무엇을 알아야 할까요?
- 자신이 받은 파일명, 자료명, 수집 날짜를 한 문장으로 말합니다.
- 한 행과 자치구 열이 뜻하는 것을 설명합니다.
- 셀 1의 준비 완료에서 다음 셀로 전달되는 파일 위치와 인코딩을 찾습니다.
관찰할 것: 단순히 “CSV 받았어”를 넘어 입력의 정체와 읽을 방법을 설명할 수 있는지 확인합니다.
다음 단계로 가기 전: 기존 셀의 값은 바꾸지 않습니다.
풀이와 확인 기준
“서울시 문화공간 정보의 해당 날짜 버전을 사용했고 한 행은 시설 기록이다. Colab의 이 파일을 CP949로 읽는다”처럼 전달할 수 있습니다.
다음 교시는 준비된 파일을 셀 2에서 DataFrame으로 읽습니다. 수집·업로드·파싱을 한 작업으로 뭉뚱그리지 않고 구분하면 진행 위치가 명확해집니다.
50-60분 · 선택 확장과 개별 복습
시간이 남으면 8주차에 선정한 자료의 출처를 다시 열어 CSV 다운로드가 있는지, 한 행이 무엇인지, 조건에 쓸 열이 있는지 확인합니다. API만 제공되는 자료는 인증키나 JSON 구조가 필요한지 메모하고 다음 학습 과제로 남깁니다.
- CSV, 다운로드, 파싱을 각각 한 문장으로 설명합니다.
- 값 안의 쉼표와 필드 사이의 쉼표를 어떻게 구분하는지 말합니다.
- 직접 받은 파일과 수업 보관본의 수집 날짜를 구분합니다.
8주차 기획에 옮겨 적용할 때의 질문
자신이 기획한 자료의 출처를 다시 열고 “어디서 받는가, 한 행은 무엇인가, 어떤 열로 선택하는가”를 순서대로 적습니다. 문화시설 대신 도서 대출 기록이나 공원 시설을 다루더라도 이 세 질문은 그대로 적용됩니다. 다만 열 이름과 기록 단위는 해당 자료에 맞게 바뀝니다.
자료가 API로만 제공된다면 인증키가 필요한지, 응답이 JSON인지, 기록 목록이 어느 항목에 들어 있는지 확인할 과제로 남깁니다. 오늘의 CSV 실습에서 아직 배우지 않은 요청 코드를 급하게 덧붙이지 않고, 이미 확보한 자료를 읽고 고르는 과정을 먼저 완성합니다.
| 질문 | 이번 공통 자료 | 나의 자료에서 채울 것 |
|---|---|---|
| 무엇을 가져오는가 | 서울시 문화공간 정보 CSV | 자료명·형식·링크 |
| 한 행은 무엇인가 | 문화시설 기록 | 개체·사건·응답 등 기록 단위 |
| 어떤 조건을 적용하는가 | 지역·종류 | 실제로 존재하는 열과 값 |
| 어떤 한계가 있는가 | 실시간 운영 정보와 구분 | 빠진 대상·갱신 시점·해석 범위 |
기억할 점 다른 자료에 적용할 때 먼저 의미를 대응시키고, 그다음 코드의 열 이름과 조건을 바꿉니다.
공식 자료
- 서울특별시: 서울시 문화공간 정보 · 공공누리 제1유형, 출처표시. 수업 보관본 수집일 2026-10-21.
- pandas: read_csv
- pandas: 인덱싱과 데이터 선택
- pandas: DataFrame.to_csv
- Python: CSV 형식과 파싱
- Python: UTF-8-SIG 인코딩
- pandas: DataFrame.head