[데이터분석]3. 인구 공공데이터

<1> 우리 동네 인구 구조 시각화

  1. 인구 데이터 파일 읽어오기
  2. 전체데이터를 한줄씩 읽음
  3. 우리 동네의 데이터인지 확인
  4. 우리 동네의 0살 ~ 100살 이상까지의 인구수를 순서대로 저장
  5. 저장된 인구수 시각화

1. 인구 데이터 파일 읽어오기, 전체 데이터 한줄씩 읽기

import csv

f = open('people.csv')
data = csv.reader(f)
for row in data:    
    print(row)

A in B 연산 이용 : A가 B에 있으면 True

print('종로구' in '서울특별시 종로구 사직동(1111053000)')
print('사직동' in '서울특별시 종로구 사직동(1111053000)')
print('()' in '서울특별시 종로구 사직동(1111053000)')

2. 특정 동네의 인구 데이터 출력

import csv

f = open('people.csv')
data = csv.reader(f)
for row in data:    
    if '신도림' in row[0]: #row[0]에 지역명 저장되어 있음
        print(row)

  • row[0] : 지역명
  • row[1], row[2] : 해당지역의 총 인구수
  • row[3] : 0~100세 이상의 인구수

3. 0~100세 이상까지의 인구수를 순서대로 저장

import csv

f = open('people.csv')
data = csv.reader(f)
for row in data:    
    if '신도림' in row[0]:
        for i in row[3:]:
            print(i)

  • 읽어온 데이터 저장
import csv

f = open('people.csv')
data = csv.reader(f)

result = []
for row in data:    
    if '신도림' in row[0]:
        for i in row[3:]:
            result.append(i)
print(result)

  • 저장된 데이터 int형으로 형변환하여 result에 저장

4. 데이터 시각화

import matplotlib.pyplot as plt

plt.style.use('ggplot') #격자무늬 스타일 지정
plt.plot(result)
plt.show()

5. 사용자 입력 받아 해당 동네 인구분포도 시각화하기

import csv
import matplotlib.pyplot as plt

f = open('people.csv')
data = csv.reader(f)

x = input('인구 구조가 알고 싶은 지역의 이름(읍면동 단위)을 입력해 주세요 :')

result = []
for row in data:    
    if x in row[0]:
        for i in row[3:]:
            result.append(int(i))
print(result)


plt.style.use('ggplot')
plt.plot(result)
plt.show()

<2> 인구 구조 다양하게 시각화하기

import csv
import matplotlib.pyplot as plt

f = open('people.csv')
data = csv.reader(f)

x = input('인구 구조가 알고 싶은 지역의 이름(읍면동 단위)을 입력해 주세요 :')

result = []
for row in data:    
    if x in row[0]:
        for i in row[3:]:
            result.append(int(i))

plt.style.use('ggplot')
plt.rc('font', family='AppleGothic')
plt.title(x + '지역의 인구 구조')
plt.plot(result)
plt.show()

1. 막대그래프 그리기

bar(막대를 표시할 위치, 막대의 높이) 함수 이용 : 막대길이는 각 데이터의 크기 의미. 두 매개변수의 개수가 동일해야 함.

import matplotlib.pyplot as plt
plt.bar([0, 1, 2, 4, 6, 10], [1, 2, 3, 5, 6, 7])
plt.show()

import matplotlib.pyplot as plt
plt.bar([0,3,2,1,6,10], [1,2,3,5,6,7])
plt.show()

  • 첫 번째 매개변수의 값의 순서는 결국 오름차순으로 정렬됨.
import matplotlib.pyplot as plt
plt.bar(range(6), [1,2,3,5,6,7])
plt.show()

  • 막대그래프의 위치를 보통 오름차순으로 표현하는 경우가 많아 range() 함수 이용하여 표현 가능함.

동네 인구구조 막대 그래프로 표현

import csv

f = open('people.csv')
data = csv.reader(f)

result = []
for row in data:    
    if '신도림' in row[0]:
        for i in row[3:]:
            result.append(int(i))
import matplotlib.pyplot as plt
plt.bar(range(101), result)
plt.show()

1.2. barh()

barh() : 수평으로 그려지는 막대 그래프

import csv

f = open('people.csv')
data = csv.reader(f)

result = []
for row in data:    
    if '신도림' in row[0]:
        for i in row[3:]:
            result.append(int(i))
import matplotlib.pyplot as plt
plt.barh(range(101), result)
plt.show()

  • range(101) : y축의 막대 위치
  • result : 막대의 너비

2. 항아리 모양 그래프 그리기

gender.csv

  • 여성 데이터와 남성 데이터가 구분없이 연속적으로 나타남.

남성데이터 : 인덱스 3부터 시작함(0살~)
여성데이터 : 인덱스 -1부터 시작함(100살~) 다시 역순으로 저장해서 정렬

1) 데이터 불러오기

import csv

f = open('gender.csv')
data = csv.reader(f)

m = []
f = []

for row in data:
    if '신림' in row[0]:
        for i in range(0,101):
            m.append(int(row[i+3]))
            f.append(int(row[-(i+1)]))
f.reverse()
print(m)

for row in data:
    if '신림' in row[0]:
        for i in range(0,101):
            m.append(int(row[i+3]))
            f.append(int(row[-(i+1)]))
f.reverse()

for row in data:
    if '신림' in row[0]:
        for i in row[3:104]:
            m.append(int(i))
        for i in row[106:]:
            f.append(int(i))
  • 두 코드는 같은 코드임

2) 데이터 시각화

  • 각 지역별로 데이터 수가 다르기 때문에 잘 확인하여 len에 맞게 시각화해야함
import csv

f = open('gender.csv')
data = csv.reader(f)

m = []
f = []

for row in data:
    if '신도림' in row[0]:
        for i in range(0,101):
            m.append(int(row[i+3]))
            f.append(int(row[-(i+1)]))
f.reverse()
print(len(m))

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
plt.title('신도림 지역의 남녀 성별 인구 분포')
plt.barh(range(101), m, label='남성')
plt.barh(range(101), f, label='여성')
plt.legend()
plt.show()

  • 두 데이터 모두가 양수로 되어 있기 때문에 그래프가 겹쳐져서 나옴
import csv

f = open('gender.csv')
data = csv.reader(f)

m = []
f = []

for row in data:
    if '신도림' in row[0]:
        for i in range(0,101):
            m.append(-int(row[i+3]))
            f.append(int(row[-(i+1)]))
f.reverse()

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
plt.title('신도림 지역의 남녀 성별 인구 분포')
plt.barh(range(101), m, label='남성')
plt.barh(range(101), f, label='여성')
plt.legend()
plt.show()

  • 남성 데이터를 음수 데이터로 변경함

3. 원하는 지역의 인구분포 시각화

import csv

f = open('gender.csv')
data = csv.reader(f)

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')
m = []
f = []

for row in data:
    if x in row[0]:
        for i in range(0,101):
            m.append(-int(row[i+3]))
            f.append(int(row[-(i+1)]))
f.reverse()

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
plt.title(x + '지역의 남녀 성별 인구 분포')
plt.barh(range(101), m, label='남성')
plt.barh(range(101), f, label='여성')
plt.legend()
plt.show()

3. 파이차트

1) 오류 해결하기

import csv

f = open('gender.csv')
data = csv.reader(f)

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')
m = []
f = []

for row in data:
    if x in row[0]:
        for i in row[3:104]:
            m.append(-int(i))
        for i in row[106:]:
            f.append(int(i))

import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.figure(figsize=(10,5),dpi=300)
plt.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
plt.title(x + '지역의 남녀 성별 인구 분포')
plt.barh(range(101), m, label='남성')
plt.barh(range(101), f, label='여성')
plt.legend()
plt.show()

  • ValueError : 지정된 x축(101개)과 데이터 개수가 일치하지 않음

  • 원본 데이터에서 신림이 포함된 단어가 3개 있기 때문에 전체 데이터 출력됨.

처음 만난 데이터만 m, f에 추가하는 코드

  • 사용자가 입력한 데이터를 만나면 1사이클을 돈 후 루프를 빠져나감.
import csv

f = open('gender.csv')
data = csv.reader(f)

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

m = []
f = []

for row in data:
    if x in row[0]:
        for i in row[3:104]:
            m.append(-int(i))
        for i in row[106:]:
            f.append(int(i))
        break

import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.figure(figsize=(10,5),dpi=300)
plt.rc('font', family='AppleGothic')
plt.rcParams['axes.unicode_minus'] = False
plt.title(x + '지역의 남녀 성별 인구 분포')
plt.barh(range(101), m, label='남성')
plt.barh(range(101), f, label='여성')
plt.legend()
plt.show()

2) 파이차트

  • 원 그래프 : 전체 데이터 중 특정 데이터의 비율

*파이차트 나타내기

import matplotlib.pyplot as plt
plt.pie([10, 20])
plt.show()

* 파이차트 정렬

import matplotlib.pyplot as plt
size = [2441, 2312, 1031, 1233]
plt.axis("equal")
plt.pie(size)
plt.show()

axis() : 더 동그란 원을 그릴 수 있음

* 레이블 추가하기

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
size = [2441, 2312, 1031, 1233]
label = ['A형', 'B형', 'O형', 'AB형']
plt.axis("equal")
plt.pie(size, labels= label)
plt.show()

  • 반시계방향으로 데이터가 표현됨.

* 비율 및 범례 표시

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
size = [2441, 2312, 1031, 1233]
label = ['A형', 'B형', 'O형', 'AB형']
plt.axis("equal")
plt.pie(size, labels= label, autopct = '%.1f%%')
plt.legend()
plt.show()

  • autopct : auto percentage, 각 항목의 비율 자동 계산
  • %.1f%% : 소수점 2번째 자리에서 반올림, 즉, 소수점 첫번째 자리까지 표현

* 색 및 돌출 효과

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
size = [2441, 2312, 1031, 1233]
label = ['A형', 'B형', 'O형', 'AB형']
color = ['darkmagenta', 'yellow', 'hotpink', 'green']
plt.axis("equal")
plt.pie(size, labels= label, autopct = '%.1f%%', colors=color, explode=(0,0,0,0.1))
plt.legend()
plt.show()

  • explode() : 특정 값을 돌출

3) 특정 지역 성별 인구 도출해내기

  • m, f 리스트들을 통해 각 성별의 전체 인구 총합을 구함
import csv

f = open('gender.csv')
data = csv.reader(f)

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

size = []

for row in data:
    m, f = 0,0
    if x in row[0]:
        for i in range(101):
            m += int(row[i+3])
            f += int(row[(i+106)])
        break
size.append(m)
size.append(f)
print(size)

import matplotlib.pyplot as plt
plt.rc('font', family='AppleGothic')
color = ['crimson', 'darkcyan']
plt.axis('equal')
plt.pie(size, labels=['man', 'woman'], autopct='%.1f%%', colors = color, startangle=90)
plt.title(x + '지역의 남녀 성별 인구 분포')
plt.show()

  • startangle : 파이차트의 시작각도 지정(파이차트 기본 시작점 : 3시방향)
  • startangle=90 : 반시계방향으로 90도 이동하므로 12시 정각 위치에서 그래프가 시작됨

4. 산점도

  • 가로축과 세로축 기준으로 두 요소가 서로 어떤 관계를 맺고 있는지 한 눈에 파악 가능
  • x축과 y축에 해당하는 데이터의 상관관계를 표현할 때 사용하며 점이 흩어져있는 그래프
  • 두 개의 축을 기준으로 데이터가 얼마나 퍼져있는지(분포) 알 수 있어 '산포도'라고도 불림

1) 꺾은선 그래프

import csv
f = open('gender.csv')
data = csv.reader(f)
m = []
f = []

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

for row in data:
    if x in row[0]:
        for i in range(3, 104):
            m.append(int(row[i]))
            f.append(int(row[(i+103)]))
        break
import matplotlib.pyplot as plt
plt.plot(m, label='Male')
plt.plot(f, label='Female')
plt.legend()
plt.show()

2) 막대그래프

import csv
f = open('gender.csv')
data = csv.reader(f)
result = []

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

for row in data:
    if x in row[0]:
        for i in range(3, 104):
            result.append(int(row[i]) - int(row[(i+103)]))
        break
import matplotlib.pyplot as plt
plt.bar(range(101), result)
plt.show()

  • 각 연령대별 남녀 성별 인원 차이 비교

3) 산점도

scatter() 함수로 표현가능

  • 가로축 : 지역의 남성 인구수
  • 세로축 : 지역의 여성 인구수
  • 산점도를 통해서 남여 인구수 사이의 관계 표현 가능
  • 그래프 오른편 컬러바(color bar) : 각 점의 색깔로 나이대 표현 가능
    • 초록색 선 : 남여 동일한 비율
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [10,30,20,40])
plt.show()

4) 버블차트

데이터를 의미하는 점들의 분포를 상관관계를 파악할 수 있음.

  • 점 크기를 다르게 하여 버블을 겹쳐서 표현 가능
  • 버블 위치 : 남녀 성비
  • 버블 크기 : 연령대별 인구수 표현
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [10,30,20,40], s = [100, 200, 250, 300])
plt.show()

  • scatter() 내 s(size) 속성을 추가하여 크기 입력
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [10,30,20,40], s = [100, 200, 250, 300], c=['red','blue','green','gold'])
plt.show()

  • c(color) 속성을 이용해 색깔 추가 가능
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [10,30,20,40], s = [100, 200, 250, 300], c=range(4))
plt.colorbar()
plt.show()

  • colorbar() 추가 : c 속성을 추가하여 표현하고 싶은 색상의 개수를 설정하면 각 데이터에 해당하는 컬러바의 색상이 정해짐
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [10,30,20,40], s = [100, 200, 250, 300], c=range(4), cmap='jet')
plt.colorbar()
plt.show()

  • cmap : 컬러맵 속성을 사용하여 컬러바에서 사용될 색상의 종류를 정할 수 있음(무지개색과 비슷한 jet컬러)

랜덤한 100개의 점 나타내기

import matplotlib.pyplot as plt
import random
x = []
y = []
size = []
for i in range(100):
    x.append(random.randint(50, 100))
    y.append(random.randint(50, 100))
    size.append(random.randint(10, 100))
plt.scatter(x, y, s=size, c=size, cmap='jet', alpha=0.7)
plt.colorbar()
plt.show()

  • alpha : 투명도 나타냄
  • c 속성 : 표현하고 싶은 색상의 수

5) 특정지역 연령대별 성별 비율 산점도로 표현

import csv
f = open('gender.csv')
data = csv.reader(f)
m = []
f = []

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

for row in data:
    if x in row[0]:
        for i in range(3, 104):
            m.append(int(row[i]))
            f.append(int(row[(i+103)]))
        break
import matplotlib.pyplot as plt
plt.scatter(m, f)
plt.show()

import csv
import math
f = open('gender.csv')
data = csv.reader(f)
m = []
f = []
size = []

x = input('찾고 싶은 지역의 이름을 알려주세요 : ')

for row in data:
    if x in row[0]:
        for i in range(3, 104):
            m.append(int(row[i]))
            f.append(int(row[(i+103)]))
            size.append(math.sqrt(int(row[i])+int(row[i+103])))
        break
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.rc('font', family='AppleGothic')
plt.figure(figsize=(10,5), dpi=300)
plt.title(x + '지역의 성별 인구 그래프')
plt.scatter(m, f, c=range(101), alpha=0.5, cmap='jet')
plt.colorbar()
plt.plot(range(max(m)), range(max(m)),'g')
plt.xlabel('남성 인구수')
plt.ylabel('여성 인구수')
plt.show()

  • plot을 통해 y=x 추세선 추가
  • sqrt 함수를 통해 점 크기 적절히 조절
  • xlabel, ylabel을 통해 각 축의 이름 설정

좋은 웹페이지 즐겨찾기