단원 홈

Ⅱ. 데이터 준비와 분석11차시

자치구별 따릉이 표를 만들면
행이 사라지고 불어난다

네 파일을 차례로 잇는 일

'대여소가 가장 많은 자치구'를 알려고 네 파일을 이었습니다. 완성된 표의 대여 건수 합계는 파일의 1.937배. 오류 메시지는 하나도 없었습니다. 행이 어디서 사라지고 어디서 불어나는지를 한 줄씩 따라가, 이은 표를 믿을 근거를 손에 넣습니다.

  • [12데과02-03]
  • 50분네 정거장
  • 새 손잡이how · indicator · validate · dropna
  • 자료따릉이 대여소 정보 2,789곳 · 2024 대여 기록 2,810곳 · 자치구 인구 50행 · 면적 25행
Ⅱ 단원 지도11 / 14차시
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14

학습 목표

  1. 개념에서

    잇는 방식(how)·모으는 단위·겹친 열쇠가 각각 행을 어떻게 없애고 불리는지 말할 수 있다.

  2. 손으로

    네 파일을 merge·groupby로 차례로 잇고, indicator와 validate로 사고를 미리 잡을 수 있다.

  3. 확인에서

    이은 표에 검산표 다섯 줄을 붙이고, 뺀 것과 그 크기를 보고서 한 줄로 적을 수 있다.

1
여는 장면 · 5분

오류 한 줄 없이 만들어진 표 — 그런데 합계가 1.937배

서울시가 연 데이터 공모전에 나간 한 팀이 '자치구별 따릉이 현황표'를 만들었습니다. 재료는 공공데이터 네 개 — 대여소 정보, 2024년 대여소별 대여 건수, 자치구 인구, 자치구 면적. 열쇠(대여소번호·자치구)로 차례차례 이었고, 코드는 오류 없이 끝까지 돌았습니다.

그런데 완성된 표의 대여 건수 합계는 84,956,060건. 원래 파일이 가진 것은 43,851,938건입니다. 1.937배 — 딱 두 배도 아닙니다. 어디선가 건수가 불어났고, 동시에 어디선가 사라졌다는 뜻입니다.

공모전 · 가상 기사

지난해 서울 따릉이 8,496만 건 — 고교생 팀이 만든 자치구별 첫 집계

공공데이터 네 개를 이어 만든 표 · 이 기사는 수업을 위해 지어낸 것입니다
표 1표를 받아 든 자리에서 셀 수 있는 것완성된 표와 원래 파일을 맞대어
무엇원래 파일완성된 표차이
대여 건수 합43,851,93884,956,060+41,104,122
행 수2,810(대여 기록)50뺄 수 없다
자치구 수2525줄은 50
오류 메시지—00

행 수는 단위가 달라(대여 기록 줄 대 자치구 줄) 그대로 뺄 수 없고, 자치구는 25개인데 줄이 50입니다. 그래도 표 자체는 멀쩡해 보입니다. 자치구 이름 25개가 다 있고, 빈칸도 없고, 숫자도 자연스럽습니다. 틀렸다고 말해 주는 것은 합계 한 줄뿐이고, 그 한 줄조차 '두 배'라는 깔끔한 모양이 아니라 1.937배입니다. 자료: 따릉이 대여소 정보(2026-06) · 대여소별 2024 대여 건수 · 주민등록 인구(2023-12 · 2024-12) · 자치구 면적 — 3정거장 코드 ①·④가 찍는 값과 같다

먼저 예측

아직 코드를 열지 않았습니다. 41,104,122건의 차이는 어디서 왔을까요 — 어떤 줄이 여러 번 세어졌을까요, 아니면 어떤 줄이 조용히 빠졌을까요, 둘 다일까요? 한 문장으로 적어 두세요. 3정거장 미션 ②의 실험실에서 여러분의 예측과 맞대어 봅니다.

체크포인트 1

오류 없이 끝난 코드가 틀린 표를 내놓을 수 있다는 것을 보았고, 차이가 어디서 왔을지 한 문장으로 적어 두었다.

다음 정거장 · 개념 15분 →
2
개념 · 15분

행이 사라지는 두 자리, 불어나는 한 자리

2-1잇는 방식이 남는 행을 정한다

두 표를 잇는다는 것은 열쇠가 같은 줄끼리 옆으로 붙인다는 뜻입니다. 그런데 한쪽에만 있는 열쇠는 어떻게 할까요? 버릴지 남길지를 정하는 것이 how입니다.

우리 두 목록은 시점이 다릅니다. 대여소 정보는 2026년 6월 기준 2,789곳, 대여 기록은 2024년 한 해의 2,810곳. 그사이 새로 생긴 대여소도, 없어진 대여소도 있으니 두 목록이 딱 맞을 리가 없습니다. 실제로 겹치는 것은 2,696곳뿐이고, 정보에만 있는 곳이 93곳, 기록에만 있는 곳이 114곳입니다.

그림 1두 목록이 겹치는 자리와 잇는 방식 넷왼쪽: 겹치는 자리 · 오른쪽: 방식 넷
두 목록이 겹치는 자리시점이 달라 딱 맞지 않는다대여소 정보 2026-06 · 2,789곳대여 기록 2024 · 2,810곳정보에만93곳둘 다2,696곳기록에만114곳칸의 넓이는 겹침을 보이려고 잡은 것 —실제 93곳·114곳은 2,789곳의 3~4%다.정보에만 있는 93곳 가운데 76곳은 2025~26년 설치다. 잇는 방식 넷 — 남는 행청록 = 결과 표에 남는 줄how=inner양쪽 모두에 있는 줄만2,696행how=left왼쪽(대여소 정보) 기준2,789행how=right오른쪽(대여 기록) 기준2,810행how=outer한쪽에만 있어도 모두2,903행 두 목록이 겹치는 자리시점이 달라 딱 맞지 않는다대여소 정보 2026-06 · 2,789곳대여 기록 2024 · 2,810곳정보에만93곳둘 다2,696곳기록에만114곳칸의 넓이는 겹침을 보이려고 잡은 것 —실제 93곳·114곳은 2,789곳의 3~4%다.정보에만 있는 93곳 가운데 76곳은 2025~26년 설치다. 잇는 방식 넷 — 남는 행청록 = 결과 표에 남는 줄how=inner양쪽 모두에 있는 줄만2,696행how=left왼쪽(대여소 정보) 기준2,789행how=right오른쪽(대여 기록) 기준2,810행how=outer한쪽에만 있어도 모두2,903행

inner는 양쪽에 다 있는 줄만, left는 왼쪽 표를 기준으로, right는 오른쪽 표를 기준으로, outer는 한쪽에만 있어도 모두 남깁니다. 같은 두 파일인데 결과가 2,696행에서 2,903행까지 갈립니다. 자료: 대여소 정보 2,789곳 × 2024 대여 기록 2,810곳 — 3정거장 코드 ①의 출력값

고를 때 기준은 '많이 남기는 쪽'이 아니라 무엇을 묻는가입니다. '자치구마다 대여소가 몇 곳인가' 같은 설비를 묻는다면 대여소 정보가 기준이므로 how="left", '2024년 대여를 한 건도 빠뜨리지 않겠다'면 how="outer"로 살려 두고 왜 짝이 없는지 확인해야 합니다.

어느 쪽을 골랐든 누가 짝을 못 찾았는지는 눈으로 봐야 합니다. indicator=True를 주면 줄마다 both·left_only·right_only가 찍힙니다 — 결과 표를 아무리 뒤져도 사라진 줄은 거기 없기 때문에, 사라진 줄을 보려면 이 표시가 필요합니다.

Ⅰ-7 에서 가져옴잇기의 뜻(열쇠 · 단위가 다른 두 표 맞추기 · 사라지는 행 세기)은 Ⅰ-7 에서 보았습니다. 여기서는 네 방식을 나란히 재고 무엇을 고를지 판정합니다.

Ⅱ-10 에서 가져옴열쇠의 모양(형)이 다르면 애초에 이어지지 않습니다. 이번 두 파일은 대여소번호가 둘 다 '00102' 꼴 글자라 dtype=str로 읽기만 하면 됩니다.

2-2모으는 자리에서 한 번 더 사라진다

how="outer"로 이으면 2,903줄을 모두 살릴 수 있습니다. 한 줄도 안 잃은 것 같지요. 그런데 이 표를 자치구로 모으면 어떻게 될까요?

기록에만 있는 114곳은 대여소 정보에 없으니 자치구 칸이 비어 있습니다. groupby("자치구")는 기본값이 dropna=True라서 열쇠가 빈 줄을 말없이 버립니다. 그래서 25행이 나오고, 대여 건수 합은 파일보다 1,373,908건(3.1%) 적어집니다 — 오류도, 경고도 없습니다.

dropna=False를 주면 26번째 무리가 나타납니다. 이름이 없는 무리, 곧 '자치구를 알 수 없는 대여' 1,373,908건입니다. 버리더라도 얼마를 버리는지 보고 버리는 것과 모르고 버리는 것은 다릅니다.

자치구로 모으기같은 2,903줄
기본 → 25행dropna=False → 26행

자료: outer 로 이은 2,903행 — 코드 ③의 출력값

2-3열쇠가 겹치면 행이 불어난다

이제 자치구 25행 표에 인구를 붙입니다. 그런데 우리가 받은 인구 파일에는 2023년 12월과 2024년 12월, 두 해가 쌓여 있습니다(25구 × 2해 = 50행).

잇기는 열쇠가 같은 줄을 모두 짝지어 줍니다. 그러니 '강남구' 한 줄에 인구 두 줄이 붙어 강남구가 두 줄이 됩니다. 25행이 50행이 되고, 대여 건수는 한 건도 더 생기지 않았는데 합계만 정확히 두 배가 됩니다. 여기서도 오류는 없습니다.

막는 방법은 두 가지입니다. 잇기 전에 열쇠가 유일한지 세어 보거나(duplicated), 아예 validate="one_to_one"이라는 자물쇠를 걸어 '한 줄에 한 줄만' 붙는 게 아니면 MergeError로 멈추게 하는 것입니다. 오류가 나는 편이 안전합니다 — 조용히 두 배가 된 표는 아무도 붙잡아 주지 않으니까요.

규칙잇기 전에 열쇠가 유일한지 확인하고, 유일해야 하는 자리에는 validate 자물쇠를 건다.

2-4이은 표를 믿는 근거 — 검산표 다섯 줄

세 사고를 한 장에 겹쳐 놓으면 1.937배의 정체가 보입니다. 불어난 몫과 사라진 몫이 서로를 가려 '대충 두 배쯤 됐네' 로 보였던 것입니다.

그림 2관문마다 대여 건수 합이 어떻게 바뀌나왼쪽: 관문마다 얼마가 남나 · 오른쪽: 장부로 적으면
관문마다 대여 건수 합막대 길이 = 대여 건수 합 · 주황 = 버려진 몫파일 · 대여 기록 2,810줄43,851,938건관문 ① merge(how="left")42,478,030건버려진 줄 1,373,908건 — 114곳관문 ② groupby("자치구")42,478,030건25행으로 모았다 — 합은 그대로관문 ③ 인구 두 해(50행)와 잇기84,956,060건한 줄에 두 줄이 붙어 두 배 차이의 회계두 사고가 서로를 가렸다두 배 몫+42,478,030건증발−1,373,908건설명 못 한 차이+41,104,12284,956,060 ÷ 43,851,938= 1.937배 — 두 배도 아니다 관문마다 대여 건수 합막대 길이 = 대여 건수 합 · 주황 = 버려진 몫파일 · 대여 기록 2,810줄43,851,938건관문 ① merge(how="left")42,478,030건버려진 줄 1,373,908건 — 114곳관문 ② groupby("자치구")42,478,030건25행으로 모았다 — 합은 그대로관문 ③ 인구 두 해(50행)와 잇기84,956,060건한 줄에 두 줄이 붙어 두 배 차이의 회계두 사고가 서로를 가렸다두 배 몫+42,478,030건증발−1,373,908건설명 못 한 차이+41,104,12284,956,060 ÷ 43,851,938= 1.937배 — 두 배도 아니다

잇는 자리에서 1,373,908건이 빠지고, 인구를 붙이는 자리에서 남은 전부가 두 배가 됩니다. 두 사고의 크기가 달라서 결과가 정확히 두 배도, 정확히 그대로도 아닌 1.937배가 되었습니다. 자료: 코드 ① · ③ · ④가 찍는 값(원장 계산)

그래서 이은 표는 결과 표의 생김새가 아니라 잇기 전후의 장부로 믿습니다. 같아야 할 두 숫자가 다른 자리를 넷만 꼽아 보면 이렇습니다.

대여 건수 합 · 잇는 동안 잃은 몫
0.0%잃을 리 없다
인데
3.1%실제로 잃었다
파일이은 뒤−3.1%

43,851,938 → 42,478,030건. 기록에만 있는 114곳의 1,373,908건이 빠졌다.

자치구 표의 행 수 · 인구를 붙이기 전후
25모은 뒤(행)
vs
50인구와 이은 뒤(행)
모은 뒤25행인구와 잇고50행

자치구가 두 번씩 — 인구 파일에 두 해가 쌓여 있다.

잇는 방식 · inner 와 outer
2,696inner(행)
vs
2,903outer(행)
inner2,696outer2,903

차이 207행 — 정보에만 93곳, 기록에만 114곳.

두 목록의 시점
2024대여 기록
인데
2026-06대여소 정보
2024대여 기록2026-06대여소 정보

2년 차이가 207곳의 어긋남을 만들었다.

자료: 위 네 쌍의 숫자는 모두 3정거장 코드 ① · ③ · ④ · ⑤가 찍는 값이다.

표 2통합 검산표 다섯 줄 — 이은 표에 반드시 붙인다
줄무엇을 맞대나이 차시에서는어긋나면
행 수 잇기 전 행 수 → 잇고 난 행 수자치구 25 → 최종 25겹친 열쇠로 불어났다
합계 보존 파일의 합 → 이은 뒤의 합43,851,938 → 42,478,030줄이 사라졌거나 두 배가 됐다
빈칸 수 붙인 열에 남은 빈칸인구 0 · 면적 0짝을 못 찾은 열쇠가 있다
열쇠 유일 결과 표의 열쇠가 한 번씩만자치구 25개 모두 한 줄다음 잇기에서 또 불어난다
단위 · 시점 각 파일이 언제·무엇을 센 것인가대여소 2026-06 · 대여 2024 · 인구 2024-12 · 면적 2025숫자는 맞아도 뜻이 다르다

다섯 줄 가운데 합계 보존만 초록이 아니어도 됩니다 — 다만 줄어든 만큼을 설명할 수 있어야 합니다. '2026년 6월 대여소 목록에 없는 114곳의 2024년 대여 1,373,908건(3.1%)은 자치구를 알 수 없어 뺐다'처럼 뺀 것 · 크기 · 까닭 셋을 함께 적으면, 줄어든 합계는 결함이 아니라 기록이 됩니다.

규칙이은 표에는 검산표 다섯 줄을 붙인다. 파생 변수(1만 명당 대여소)는 검산을 통과한 뒤에 만든다.

체크포인트 2

행이 사라지는 두 자리(잇기 · 모으기)와 불어나는 한 자리(겹친 열쇠)를 말할 수 있고, 검산표 다섯 줄을 안다. 이제 한 줄씩 직접 따라가 본다.

다음 정거장 · 손으로 20분 →
3
손으로 · 20분

네 파일을 차례로 이어, 한 줄도 남기지 않고 장부를 맞춘다

오늘의 장비

merge 의 세 손잡이 — how · indicator · validate

Ⅰ-7 과 Ⅱ-10 에서 pd.merge 로 두 표를 이어 보았습니다. 그때는 열쇠가 딱 맞는 표였어요. 오늘은 딱 맞지 않는 표를 잇습니다 — 그때 쓰는 손잡이 셋과, 모으기 쪽의 손잡이 하나를 더합니다.

부르는 모양

pd.merge(왼쪽, 오른쪽,
         on="대여소번호",
         how="left",        # 남길 줄
         indicator=True,    # 어디서 왔나
         validate="one_to_one")

오늘 쓰는 손잡이 넷

how
남길 줄을 정한다 — inner·left·right·outer
indicator
줄마다 어느 쪽에서 왔는지 표시(_merge 열)
validate
짝의 개수를 못 박는다 — 어기면 MergeError
dropna
groupby에서 열쇠가 빈 줄을 버릴지 말지

앞 차시와 다른 셋

  1. 열쇠가 안 맞는다Ⅱ-10 은 366일 대 366일이었다 — 오늘은 2,789 대 2,810
  2. 표가 넷한 번이 아니라 네 번 이으므로 사고가 쌓인다
  3. 오류가 안 난다그래서 내가 검산표를 붙여야 한다

대가 — validate 를 걸면 코드가 더 자주 멈춥니다. 멈추는 것이 이 손잡이의 일입니다.

1

네 가지로 이어 본다 — 남는 행이 다르다

3분

대여소 정보는 2,789곳, 대여 기록은 2,810곳입니다. inner 로 이으면 몇 행이 될까요? outer 면요? 네 숫자를 먼저 짐작해 두고 실행하세요 — 맞히는 것이 목적이 아니라 어긋난 자리를 기억하는 것이 목적입니다.

기본 빈칸 ①에 잇는 방식을 채우고 ▶ 실행합니다. 이 표가 답할 물음은 '자치구마다 대여소가 몇 곳인가' — 설비를 묻습니다. 그러면 어느 표가 기준이어야 할까요?

도전 두 read_csv 에서 dtype=ids 를 둘 다 지워 보세요. 번호가 수 102 로 읽혀도 잇기는 되지만 '00102' 모양을 잃습니다. 한쪽만 지우면 어떻게 될까요 — 글자와 수는 짝이 되지 않아 ValueError 로 멈춥니다.

탐구 대여소 수를 '2024년에 있던 대여소'로 맞추려면 무엇을 해야 할까요? stations.csv 의 설치일 열로 무엇을 거를지 한 줄로 적어 보세요.

정보에만 있는 93곳은 이고, 기록에만 있는 114곳은 이다. 설비를 묻는 표이므로 how= 를 골랐다.

확인 문제 1에 적어 제출 →
2

한 줄 추적기 — 꼬리표 한 장을 네 파일에 떨어뜨린다

10분

여는 장면에 적어 둔 내 예측입니다. 41,104,122건의 차이는 불어난 것일까요, 사라진 것일까요?

표 전체를 보면 알 수 없습니다. 줄 하나를 골라 끝까지 따라가면 보입니다.

실험실에서 꼬리표를 한 장 집습니다 — 꼬리표란 대여 기록 한 줄에 붙인 이름표로, 대여소번호 하나와 그 해 대여 건수가 적혀 있습니다. 이 꼬리표를 관문 다섯 개에 차례로 떨어뜨립니다. 관문은 pandas 코드 한 줄이고, 관문을 여는 손잡이가 빗장입니다 — 몇 줄이 되는지 먼저 잠가야 빗장이 풀립니다. 목표는 사건 판의 「설명 못 한 차이」를 0 으로 만드는 것입니다.

시뮬레이터

한 줄 추적기

표가 아니라 한 줄의 운명을 따라간다 — 차이 계수기를 0 으로

  1. 1꼬리표 통에서 한 장을 집는다
  2. 2관문마다 몇 줄이 되나를 잠그고 빗장을 톡 친다
  3. 3같은 운명을 모아 '설명 못 한 차이'를 0 으로
먼저 예측 — 완성 표 합계는 파일의 몇 배?
사건 — 설정 한 벌
꼬리표 통
이 관문에서 몇 줄이 되나 — 잠그면 빗장이 풀린다
관문 ① 잇는 방식 · 관문 ② 모으기
관문 ③ 인구 표 · 자물쇠
사건 1 · 공모전 팀이 한 대로꼬리표를 한 장 집어 관문 ① 위에 올린다

경로 = 꼬리표 한 장이 관문마다 몇 줄이 되는가를 이어 적은 것(예 1·1·1·2·2). 경로가 같은 줄은 운명이 같다 — 같은 운명 모으기가 그 줄 수와 대여 건수 몫을 계수기에서 뺀다

설명 못 한 차이 = (완성 표의 대여 건수 합 − 파일 합) − 이미 모은 몫. 0 이 되면 표의 모든 건이 어디서 불어나고 어디서 사라졌는지 다 적은 것이다 — 그때 검산표의 '합계 보존' 줄이 초록이 된다

설명 못 한 차이—건
완성 표 행—
완성 표 대여 건수 합—
지금 꼬리표—
이 줄의 경로—
모은 줄0
도전 1

사라진 줄을 붙잡아라. 결과 표에 없는 줄을 꼬리표로 들고 관문 ①에 떨어뜨린 뒤, 같은 운명 모으기로 그 몫을 계수기에서 빼라.

도전 2

두 배를 멈춰라. 관문 ③의 설정만 바꿔 완성 표를 25행으로, 대여 건수 합을 42,478,030으로 되돌려라.

도전 3

차이 0. 검산표 다섯 줄을 모두 초록으로 만들어 보고서 한 줄을 받아라.

자료: 판이 쪽 안에 실린 네 파일을 브라우저에서 실제로 잇는다 — 대여소 정보 2,789곳(공공데이터포털 OA-13252 · 2026-06 스냅숏, 번호 · 이름 · 자치구 · 설치 연도) · 대여소별 2024 대여 건수 2,810곳(대여이력 OA-15182 를 대여 대여소번호로 센 것) · 자치구 인구 2023-12 · 2024-12(행정안전부 주민등록 — 원장이 연도 접두어를 떼고 '자치구 · 연도 · 인구' 50행으로 쌓았다) · 자치구 면적 25행. 2,696 · 93 · 114 · 43,851,938 같은 숫자는 미리 적어 둔 것이 아니라 판이 그 자리에서 다시 센 값이고, 쪽이 열릴 때 원장 값과 맞대어 본다(어긋나면 콘솔에 남는다).

기본 코드 ②는 채워져 있습니다. n 에 실험실에서 추적한 번호를 넣고 ▶ 실행해, 판에서 잠근 0 · 1 · 2 가 pandas 에서도 그대로 나오는지 맞대어 보세요.

도전 n 을 "00102" 로 바꾸면 넷 모두 1줄입니다. 두 목록에 다 있는 번호이기 때문이지요. 실험실에서 램프가 비춘 다른 번호도 넣어 보세요 — 0 · 0 · 1 · 1 이 반복됩니다.

탐구 04065 처럼 대여 기록에만 있는 번호가 114곳입니다. 보고서에서 이 114곳을 ① 버린다 ② '자치구 모름'으로 따로 적는다 ③ 대여소 목록을 다시 받는다 가운데 어느 쪽으로 다루겠습니까? 하나를 고르고, 이 보고서를 받는 사람이 누구인지와 함께 까닭을 적어 보세요.

계수기가 에서 출발해 이 된 것은, 표의 모든 건이 와 둘 가운데 하나로 설명되었다는 뜻이다.

확인 문제 4에 보고서 한 줄을 적어 제출 →
3

자치구로 모으면 — 빈 열쇠는 조용히 빠진다

2분

outer 로 이어 2,903행을 모두 살렸습니다. 한 줄도 안 버렸지요. 이제 자치구로 모아 더하면, 대여 건수 합은 파일의 43,851,938건과 같을까요?

기본 빈칸 ②에 빈 자치구도 한 무리로 세라는 값을 채우고 ▶ 실행합니다.

도전 how="outer" 를 "left" 로 바꿔 보세요. 모은 합은 똑같은 42,478,030 인데 26번째 무리가 없습니다. 같은 손실이 다른 자리에서 일어났기 때문입니다 — 어느 자리일까요?

탐구 '오류 없이 조용히 사라지는' 자리를 이 단원에서 또 어디서 보았나요? (Ⅱ-10 의 오류 없는 0행 · Ⅱ-4 의 isna 가 못 세는 빈칸) 세 자리의 공통점을 한 줄로 적고, 앞으로 코드를 돌릴 때마다 무엇을 찍어 볼지 여러분의 검산 습관을 하나 정해 적어 보세요.

outer 로 살린 줄이 다시 사라진 자리는 이고, 그것을 드러내는 손잡이는 이다. 오류 없이 사라지는 자리는 이 차시에만 곳이다.

확인 문제 2에 적어 제출 →
4

인구와 이으면 — 행이 불어난다

2분

자치구 25행 표를 인구 파일(50행)과 이으면 몇 행이 될까요? 대여 건수 합은 어떻게 될까요? 두 숫자를 먼저 적어 두세요.

기본 빈칸 ③에 한 줄에 한 줄만 붙어야 한다는 자물쇠 값을 채우고 ▶ 실행합니다. 이 칸은 마지막 줄에서 MergeError 로 멈추는 것이 정답입니다 — 오류가 이 칸의 결과물이에요. 앞의 두 줄은 오류 없이 틀리고, 마지막 줄은 오류로 막습니다.

도전 마지막 줄 앞에 pop = pop[pop["연도"] == 2024] 한 줄을 더해 보세요. 이번에는 멈추지 않습니다. 잇기 전에 열쇠를 유일하게 만들었기 때문입니다.

탐구 인구 파일은 원래 두 해가 옆으로 붙어 옵니다(열 이름에 연도가 박힌 seoul_pop_gu.csv). 원장이 세로로 쌓은 이 50행과 무엇이 다를까요 — 어느 모양이 잇기에 안전한가요?

오류 없이 두 배가 된 표와 오류로 멈춘 줄 가운데 더 안전한 것은 이다. 까닭은 이고, 그래서 나는 자리마다 자물쇠를 걸겠다.

확인 문제 3에 적어 제출 →
5

바르게 잇고, 파생 변수 하나, 검산표 다섯 줄

3분

이제 제대로 잇습니다. 마지막에 파생 변수 하나 — 주민 1만 명당 대여소를 만듭니다. 이 값이 가장 큰 구는 어디일까요? (다음 차시 Ⅱ-12 에서 이 숫자를 다시 씁니다.)

기본 빈칸 ④에 '1만 명당'으로 만드는 수를 채우고 ▶ 실행합니다. 출력 아래 검산표 다섯 줄을 눈으로 읽으세요 — 이 다섯 줄이 오늘의 결과물입니다.

도전 첫 merge 의 how="left" 를 "inner" 로 바꿔 보세요. 검산표의 대여소 합이 2,789 → 2,696 으로 줄어듭니다 — 이번에는 설비 수까지 줄어든 것이지요 (정보에만 있는 93곳이 빠졌습니다). 대여 건수 합은 42,478,030 그대로입니다.

탐구 검산표 다섯 줄 가운데 이 표에서 가장 중요한 줄은 무엇일까요 — 여러분이 이 표를 받는 사람이라면 어느 줄부터 보겠습니까?

이 표의 대여 건수 합은 파일보다 건 적다. 그 몫은 이고, 보고서에는 라고 적는다.

확인 문제 4의 표를 채워 제출 →
체크포인트 3

네 파일을 차례로 이어 25행 표를 만들었고, 한 줄의 운명을 끝까지 따라가 설명 못 한 차이를 0 으로 만들었고, 이은 표에 붙일 검산표 다섯 줄을 손에 넣었다.

다음 정거장 · 정리·확인 10분 →
4
정리·확인 · 10분

오늘의 탐험 일지

  1. 찾은 것

    행은 세 자리에서 달라진다 — 잇는 방식(how)이 버리고, 모으기(dropna)가 또 버리고, 겹친 열쇠가 불린다. 셋 다 오류 없이 일어난다.

  2. 도구의 한계

    결과 표는 사라진 줄을 보여 주지 못한다 — 거기 없으니까. 그래서 indicator로 표시하고, validate로 미리 멈춘다.

  3. 보고의 규칙

    이은 표에는 검산표 다섯 줄을 붙인다. 줄어든 합계는 결함이 아니라 뺀 것 · 크기 · 까닭을 적으면 기록이 된다.

✍️ 문제마다 답을 쓰고 제출하기를 누르세요. 제출하면 모범 답안이 열리고, 제출한 답은 선생님께 전달됩니다.

1. inner 로 이었더니 2,696행, outer 로 이었더니 2,903행이었다. 차이 207행은 각각 무엇이고, '자치구마다 대여소가 몇 곳인가'를 묻는 표라면 어느 방식을 골라야 하는지 까닭과 함께 쓰시오.
📖 모범 답안

대여소 정보에만 있는 93곳과 대여 기록에만 있는 114곳이다(93 + 114 = 207). 93곳은 대부분 2024년에는 없던 대여소다 — 설치일을 보면 76곳이 2025~2026년 설치이고, 목록이 2026년 6월 기준이기 때문이다. 114곳은 2024년에는 대여가 있었지만 2026년 6월 목록에는 없는 번호, 곧 그사이 없어지거나 번호가 바뀐 대여소다.

이 표가 답할 물음은 설비('자치구마다 대여소가 몇 곳인가')이므로 기준은 대여소 정보다 → how="left", 2,789행. inner 로 하면 2024년에 대여가 없던 93곳이 설비 집계에서 빠지고, outer 로 하면 지금은 없는 114곳이 설비에 섞인다. 반대로 '2024년 대여를 한 건도 빠뜨리지 않겠다'가 물음이라면 outer 로 살려 두고 짝이 없는 줄을 따로 보고해야 한다. 많이 남기는 쪽이 아니라 묻는 물음이 방식을 정한다.

2. how="outer" 로 이어 2,903줄을 모두 살렸는데, 자치구로 모은 뒤 대여 건수 합이 파일보다 1,373,908건 적었다. 원인과 코드로 확인하는 법을 쓰고, 이 차시에서 '오류 없이 조용히 사라지는' 자리가 몇 군데였는지 짚으시오.
📖 모범 답안

대여 기록에만 있는 114곳은 대여소 정보에 없으니 자치구 칸이 비어 있다. groupby("자치구") 는 기본값이 dropna=True 라서 열쇠가 빈 줄을 말없이 버린다. 그래서 25행이 되고 합이 42,478,030 으로 줄었다.

확인하는 법: sc["자치구"].isna().sum() 으로 빈 줄을 세거나, groupby("자치구", dropna=False) 로 모아 26번째 무리(NaN)를 드러낸다 — 그 무리의 합이 정확히 1,373,908 이고, 26행짜리 합은 파일 합 43,851,938 과 같아진다.

오류 없이 사라지는 자리는 두 군데다 — ① 잇기(how="left" 면 짝 없는 줄이 여기서 빠진다) ② 모으기(how="outer" 로 살려도 groupby 가 빈 열쇠를 버린다). left 와 outer 는 같은 1,373,908건을 서로 다른 자리에서 잃는다. 그래서 '한 줄도 안 버렸다'는 말은 마지막 표까지 세어 봐야 할 수 있는 말이다.

3. 인구 파일에 두 해(2023-12 · 2024-12)가 섞인 줄 모르고 이었다. ① 결과의 어느 숫자를 보면 알아챌 수 있었는지, ② 잇기 전에 막는 법 두 가지를 쓰고, ③ 오류 없이 두 배가 된 표와 MergeError 로 멈춘 줄 가운데 어느 쪽이 더 안전한지 까닭과 함께 쓰시오.
📖 모범 답안

① 행 수(25 → 50)와 대여 건수 합(42,478,030 → 84,956,060, 정확히 두 배)이다. 대여 건수는 인구를 붙인다고 늘어날 까닭이 없는 값이므로, 합이 변했다는 것 자체가 신호다. 열을 보면 연도 열에 [2023, 2024] 가 들어 있다.

② 잇기 전에 pop["자치구"].duplicated().sum() 으로 열쇠가 유일한지 세어 보거나(25가 나오면 겹친 것이다), validate="one_to_one" 자물쇠를 걸어 겹치면 MergeError 로 멈추게 한다. 아예 pop = pop[pop["연도"] == 2024] 로 한 시점만 남겨 열쇠를 유일하게 만드는 것도 같은 일이다.

③ 멈춘 쪽이 안전하다. 오류는 즉시 · 정확한 자리에서 알려 주지만, 두 배가 된 표는 아무도 알려 주지 않은 채 다음 계산으로 흘러간다. 이 차시에서 그 표가 실제로 기사까지 나갔다 — 오류가 없다는 것은 문법이 맞았다는 뜻이지 뜻이 맞았다는 뜻이 아니다. 그래서 '한 줄에 한 줄'이어야 하는 자리에는 미리 자물쇠를 건다.

4. 최종 25행 표의 대여 건수 합이 파일 43,851,938 → 이은 뒤 42,478,030 으로 1,373,908건 줄었다. 아래 검산표 다섯 줄을 채우고, 무엇이 빠졌는지와 그것을 보고서에 어떻게 적을지 한 문장으로 쓰시오.
검산 줄내 표에서는 얼마인가통과? 아니라면 까닭
행 수
합계 보존
빈칸 수
열쇠 유일
단위 · 시점
📖 모범 답안

검산표 — 행 수: 자치구 25 → 최종 25 통과. / 합계 보존: 43,851,938 → 42,478,030, 1,373,908건 줄었다 — 통과는 아니지만 줄어든 몫을 설명할 수 있다. / 빈칸 수: 인구 0 · 면적 0 통과. / 열쇠 유일: 자치구 25개가 한 줄씩(is_unique True) 통과. / 단위 · 시점: 대여소 2026-06 · 대여 2024 · 인구 2024-12 · 면적 2025 — 시점이 서로 다르다는 사실을 적어 두면 통과.

빠진 것 — 2024년 대여 기록에는 있지만 2026년 6월 대여소 목록에는 없는 114곳의 대여다. 이 줄들은 자치구를 알 수 없어 how="left" 잇기에서(또는 outer 로 살렸더라도 groupby 에서) 빠졌다.

보고서 한 줄(예) “2026년 6월 대여소 목록에 없는 114곳의 2024년 대여 1,373,908건(전체의 3.1%)은 자치구를 알 수 없어 집계에서 뺐다 — 목록과 기록의 시점이 다르다.” 뺀 것 · 크기 · 까닭 셋이 다 들어가야 한다. 크기를 %로도 적는 까닭은, 받는 사람이 이 정도면 무시해도 되는가를 스스로 판단할 수 있어야 하기 때문이다.

5. 인구 파일이 '서울특별시 종로구 (1111000000)' 처럼 이름과 코드를 함께 준다면, 자치구 이름 대신 행정구역 코드로 잇는 편이 더 안전한 경우를 두 가지 이상 들고 까닭을 쓰시오.
📖 모범 답안

① 이름 표기가 파일마다 다를 때 — '서울특별시 종로구' · '종로구' · '서울 종로구' 처럼 앞말이 붙거나, 띄어쓰기·괄호·공백이 다르면 사람 눈에는 같은데 컴퓨터에는 다른 열쇠다. 이 차시에서도 원장이 이름을 '○○구'로 다듬어 둔 덕분에 이어졌다.

② 다른 시·도와 합칠 때 — '중구'는 서울·부산·대구·인천·대전에 모두 있다. 이름으로 이으면 전혀 다른 지역이 한 줄로 붙는다. 코드는 전국에서 유일하므로 이런 사고가 없다.

③ 이름이 바뀌는 해 — 행정구역 이름이 바뀌어도 코드가 유지되는 경우가 있어, 여러 해를 이을 때 코드 쪽이 끊기지 않는다. (반대로 통합·분리로 코드가 바뀌는 해도 있으므로, 어느 쪽이든 기준 시점은 검산표 '단위 · 시점' 줄에 적어 둔다.)

한마디로 열쇠는 뜻이 아니라 식별자여야 한다. 사람이 읽는 이름은 표기가 흔들리지만, 코드는 흔들리지 않게 만들어 둔 값이다.

+
더 알아보기

열쇠를 둘러싼 이야기 셋

같은 땅, 두 벌의 경계실선 = 법정동(주소에 쓰는 동)점선 = 행정동(주민센터가 맡는 동)법정동 가법정동 나법정동 다행정동 1행정동 2행정동 3행정동 4법정동 나 하나가행정동 2 와 3 에 걸친다한쪽의 한 줄이 다른 쪽 여러 줄과 짝을 이룬다 — 다대다‘한 줄에 한 줄’ 자물쇠가 애초에 걸리지 않는 자리
현장

법정동과 행정동 — 같은 땅, 두 벌의 경계

오늘은 자치구로 이었습니다. 한 단계만 더 내려가 동으로 이으려 하면 갑자기 어려워집니다. 우리나라에는 같은 땅 위에 두 벌의 동이 있기 때문입니다. 주소에 쓰는 법정동은 오래전부터 내려온 땅 이름이라 좀처럼 바뀌지 않고, 주민센터가 맡는 행정동은 사람이 많으면 쪼개고 적으면 합쳐서 인구에 따라 바뀝니다.

그래서 경계가 서로 어긋납니다. 한 법정동이 여러 행정동에 걸치기도 하고, 한 행정동이 여러 법정동을 품기도 합니다 — 곧 다대다입니다. 이런 두 표를 동 이름으로 이으면 오늘 본 사고가 한꺼번에 일어납니다. 한쪽 한 줄이 다른 쪽 여러 줄과 짝을 이루어 행이 불어나고, 어느 벌에도 없는 이름은 조용히 빠집니다. 게다가 validate="one_to_one" 같은 자물쇠는 애초에 걸 수 없습니다 — 1대1이 아닌 것이 정상이니까요.

실무에서 쓰는 방법은 둘입니다. 어느 벌인지를 먼저 확인하고(공공데이터는 대개 열 이름이나 안내문에 적어 둡니다), 둘을 이어야 한다면 땅 넓이나 인구로 나눠 배분하는 표를 따로 구해 두 단계로 잇습니다. 어느 쪽이든 '한 줄이 한 줄에 대응한다'는 가정부터 버리는 것이 시작입니다.

도해: 법정동 셋(실선)과 행정동 넷(점선)의 경계가 어긋난 모식 지도 — 법정동 나 하나가 행정동 2 와 3 에 걸친다. 실제 지도가 아니라 관계를 보이는 그림이다.

조사원 대신 ‘잇기’ 가 센다이미 있는 행정자료를 열쇠로 이어 통계를 만든다주민등록외국인등록건축물대장그 밖의 행정자료열쇠사람 · 주택인구주택총조사(등록센서스)빠지는 줄의 자리가 옮겨 간다 — 못 만난 집에서 어긋난 열쇠로일부 항목은 여전히 표본으로 묻는다
역사

조사원 대신 '잇기'가 센다 — 등록센서스

인구주택총조사는 오랫동안 조사원이 집집마다 찾아가 묻는 일이었습니다. 5년마다 수십만 명이 동원되는 거대한 작업이었고, 비용도 시간도 컸지요. 통계청은 2015년부터 방식을 바꿨습니다. 주민등록·외국인등록·건축물대장처럼 이미 나라 안에 쌓여 있는 행정자료를 사람과 주택이라는 열쇠로 이어서 통계를 만드는 것입니다. 이것을 등록센서스라고 부릅니다.

오늘 우리가 대여소번호로 두 표를 이은 일과 원리가 같습니다. 규모만 다를 뿐이지요. 그래서 사고의 갈래도 같습니다. 조사원 방식에서는 '못 만난 집'이 빠졌다면, 잇기 방식에서는 열쇠가 어긋난 줄이 빠집니다 — 오늘 본 114곳과 정확히 같은 갈래입니다. 대신 해마다 만들 수 있을 만큼 빨라졌고, 같은 자료를 여러 통계가 나눠 쓸 수 있게 되었습니다.

잇기가 모든 것을 대신하지는 못합니다. 행정자료에 없는 항목 — 이를테면 통근·통학 수단이나 혼인 상태의 일부 — 은 여전히 일부 가구에만 묻는 표본조사로 채웁니다. 전수로 이은 부분과 표본으로 물은 부분이 한 통계 안에 함께 들어 있는 셈이라, 어느 숫자가 어느 방식에서 왔는지를 표에 적어 둡니다. 오늘 우리가 검산표의 '단위 · 시점' 줄에 적은 것과 같은 일입니다.

도해: 행정자료 넷이 사람·주택 열쇠로 모여 인구주택총조사가 되는 그림. 상자 이름은 자료의 갈래를 보이는 예시다.

열쇠가 없을 때 잇기공통 번호가 없으면 속성을 하나씩 맞댄다속성명부 A명부 B같은가이름김○○김○○같다생년월일2009-03-042009-03-04같다주소○○구 △△로◇◇구 □□로다르다전화010-…-1234(비어 있음)알 수 없다점수를 더해 문턱을 넘으면 같은 사람으로 잇는다잘못 이음다른 두 사람을 한 사람으로못 이음한 사람을 둘로 셈문턱을 낮추면 앞이, 높이면 뒤가 늘어난다
방법 더 깊이

열쇠가 없을 때 잇기 — 레코드 연계

오늘은 대여소번호라는 깔끔한 열쇠가 있었습니다. 그런데 두 명부에 공통 번호가 없다면요? 옛 병원 기록과 오늘의 진료 기록, 서로 다른 나라의 명부, 개인정보 때문에 번호를 지운 자료 — 이런 자리에서는 이름 · 생년월일 · 주소처럼 완전하지 않은 속성만으로 '같은 사람인가'를 가려야 합니다. 이것을 레코드 연계라고 합니다.

방법은 이렇습니다. 두 줄을 맞대어 속성마다 같은가 · 다른가 · 알 수 없는가를 보고, 속성마다 점수를 줍니다. 흔한 이름이 같은 것보다 드문 이름이 같은 쪽에 더 큰 점수를 주고, 주소처럼 잘 바뀌는 속성은 달라도 벌점을 적게 줍니다. 점수를 더해 문턱을 넘으면 같은 사람으로 잇습니다. 이 틀을 수학으로 정리한 것이 펠레기–선터 모형(1969)이고, 오늘날 통계기관이 쓰는 연계의 바탕입니다.

여기서는 오류가 두 갈래로 생깁니다. 잘못 이음 — 다른 두 사람을 한 사람으로 묶는 것과, 못 이음 — 한 사람을 둘로 세는 것입니다. 문턱을 낮추면 앞이 늘고, 높이면 뒤가 늘어서 둘을 함께 0 으로 만들 수는 없습니다. 그래서 연계 결과에는 늘 '얼마나 이었고 얼마를 못 이었나'가 함께 붙습니다 — 오늘 우리가 114곳을 세어 적은 것과 같은 자리입니다. 열쇠가 있든 없든, 이은 표에는 장부가 따라붙습니다.

도해: 두 명부의 비슷한 두 줄을 속성마다 맞댄 표와, 문턱을 넘어 잇거나 못 이을 때 생기는 두 가지 오류. 이름·주소는 모양을 보인 예시다. · 출처: I. P. Fellegi & A. B. Sunter, “A Theory for Record Linkage”, JASA, 1969