#################### 빅데이터이용
'''
행정안전부 : <https://www.mois.go.kr/>
정책자료 -> 연령별 인구현황 -> csv파일 다운
'''
📌
import numpy as np
import csv
import re
f = open("data/age.csv")
data = csv.reader(f) # csv 형태의 파일을 읽어 저장
type(data) # _csv.reader
data # 반복문을 통해 한행씩 조회가능
import matplotlib.pyplot as plt
name = "역삼"
for row in data : # row : 한개의 행
if row[0].find(name) >= 0 : # 행정구역의 내용에 name값이 존재?
print(row)
name=row[0]
# 숫자의 , 제거
row = list(map((lambda x : x.replace(",","")), row))
print(row)
# 0세 컬럼 이후의 셀들을 배열로 생성
home = np.array(row[3:],dtype=int)
print(home)
break # 반복문 종료
# home : 해당 동(읍)의 나이별 인구수를 배열로 저장
plt.style.use('ggplot') # 그래프 스타일 설정
plt.figure(figsize=(10,5),dpi=100) # 그래프 크기 지정
plt.rc('font',family='Malgun Gothic') # 한글 설정
plt.title(name + ' 지역의 인구 구조') # 그래프 제목 설정
plt.plot(home) # 선 그래프 출력
'''
기본 함수
np.arange(15) : 0 ~ 14까지의 숫자를 1차원 배열로 생성
arr.reshape(3,5) : 3행5열의 2차원배열로 생성. 배열 갯수가 맞아야 함.
arr.dtype : 배열 요소의 자료형
arr.shape :배열 구조 행열값
arr.ndim : 배열의 차수
arr.itemsize : 요소의 바이트 크기
arr.size : 요소의 갯수
np.zeros((행,열)) : 요소의 값이 0인 배열 생성
np.ones((행,열)) : 요소의 값이 1인 배열 생성
np.ones(10,dtype=자료형)
np.eye(10,10) #10행10열 단위 행렬
np.linspace(시작값,종료값,갯수) : 시작값부터 종료값까지 갯수만큼 균등분할하는 수치
np.pi : 원주율 상수
난수 관련 함수
np.random.random() : 난수 발생
np.random.default_rng(1) : seed 값 설정
np.random.randint: 정수형 난수 리턴.
np.random.normal(평균,표준편차,데이터갯수) : 정규 분포 난수 생성
np.random.choice(값의범위,선택갯수,재선택여부)
np.random.choice(값의범위,선택갯수,확률)
통계 관련 함수
sum,min,max,mean,std
max(axis=1) : 행중 최대값
max(axis=0) : 열중 최대값
cumsum(axis=1) : 행의 누적 합계
cumsum(axis=0) : 열의 누적 합계
argmax(axis=1) : 행 중 최대값의 인덱스
argmin(axis=1) : 행 중 최소값의 인덱스
argmax(axis=0) : 열 중 최대값의 인덱스
argmin(axis=0) : 열 중 최소값의 인덱스
np.fromfunction() : 함수를 이용하여 요소의 값 설정
arr.flat:배열의 요소들만 리턴
np.floor: 작은 근사정수
np.ceil : 큰 근사정수
arr.ravel() #1차원배열로 변경
arr.resize() : 배열 객체 자체를 변경
2개의 배열을 합하기
np.vstack((i,j)) #행기준 합. 열의 갯수가 같아야 함
np.hstack((i,j)) #열기준 합. 행의 갯수가 같아야 함.
배열 나누기
np.hsplit(k,3) #3개로 열을 분리.
np.vsplit(k,2) #2개로 행을 분리.
'''
📌
# test1207 내용 중
'''
0. 인구구조의 그래프 제목에 코드값 제거하기
'''
import csv
f = open("data/age.csv")
data = csv.reader(f) # csv 형태의 파일을 읽어 저장
type(data) # csv형태 파일. _csv.reader
data # 반복문을 통해 한행씩 조회가능.
import re # 정규식 이용을 위한 모듈
import numpy as np
import matplotlib.pyplot as plt
name = "신사"
# data를 반복문으로 읽으면, 다시 처음부터 시작 할 수 없음.
# 처음부터 다시 시작하고 싶으면 다시 읽어야 한다.
for row in data : # row : 한개의 행
if row[0].find(name) >= 0 : # 행정구역의 내용에 name값이 존재?
print(row)
name=row[0]
# row[0]의 코드값 제거
# re.sub(패턴 문자, 변경문자, 대상이 되는 문자열) : 치환 함수
# \\( : 그룹을 의미하는 것이 아니고 ( 문자를 의미.
# \\\\d : 숫자0개 이상을 의미
# \\) : )문자를 의미.
name = re.sub("\\(\\d*\\)","",row[0])
# 숫자의 , 제거
row = list(map((lambda x : x.replace(",","")), row))
print(row)
# 0세 컬럼 이후의 셀들을 배열로 생성
home = np.array(row[3:],dtype=int)
print(home)
break # 반복문 종료
# home : 해당 동(읍)의 나이별 인구수를 배열로 저장
plt.style.use('ggplot') # 그래프 스타일 설정
plt.figure(figsize=(10,5),dpi=100) # 그래프 크기 지정
plt.rc('font',family='Malgun Gothic') # 한글 설정
plt.title(name + ' 지역의 인구 구조') # 그래프 제목 설정
plt.plot(home) # 선 그래프 출력
### 같은 이름을 포함한 동이 있는 경우 모든 동을 하나의 그래프로 작성하기
f = open("data/age.csv") # f : IOStream
data = csv.reader(f) # data : age.csv 파일의 정보를 저장하고 있는 객체.
# 스트림을 통해 들어왔기 때문에 되돌릴 수는 없다.
next(data) # 한줄을 읽기.
data = list(data) # 파일스트림데이터를 리스트객체로 변경
# 파일내용을 리스트로 저장
data # 리스트 객체
name = "신사"
homelist = [] # 신사라는 이름을 가진 행정동의 인구데이터를 저장해주는 리스트 객체
namelist = [] # 동이름목록을 저장
for row in data :
# row : 각 동별 인구데이터 한개.
if row[0].find(name) >= 0 :
# 숫자의 , 를 제거
row = list(map((lambda x:x.replace(",","")),row))
# row[3:] : 0세이후 인구목록
homelist.append(np.array(row[3:],dtype = int))
# 동의 이름을 (이전 부분까지만 이름 목록에 추가
# row[0].find('(') : row[0]문자열에서 '('문자의 인덱스
namelist.append(row[0][:row[0].find('(')])
plt.style.use('ggplot')
plt.figure(figsize=(10,5),dpi=100)
plt.rc('font', family='Malgun Gothic')
plt.title(name + '지역의 인구 구조')
for h,n in zip(homelist,namelist) :
# h : 그래프로 출력할 데이터
# n : 동의 이름
plt.plot(h,label=n) # 하나의 그래프에 여러개의 선그래프 작성
plt.legend() # 범례 출력
📌
### age.csv 파일을 이용하여 선택한 지역의 인구구조와
# 가장 비슷한 인구구조를 가진 지역의 그래프와 지역 출력하기.
# 가장 비슷한 지역 한개만 그래프로 출력하기.
name = "역삼1동"
for row in data :
if name in row[0] : #row[0] 문자열에 name포함?
#,를 제거 : 숫자내부의, 제거
row = list(map((lambda x:x.replace(",","")),row))
#np.array
#int(row[2]) : 정수형 총인구수
#home : 0세이후 인구수를 정수형배열 / 총인구수
# 총인구수 대비 각각의 나이의 비율 목록
# name에 해당하는 동의 나이별 인구 비율 목록
home = np.array(row[3:],dtype=int) / int(row[2])
home_name = re.sub('\\(\\\\d*\\)','',row[0])
mn = 1
for row in data :
#숫자의 ,제거
row = list(map((lambda x:x.replace(",","")),row))
#현재 레코드의 인구 비율 정보
away = np.array(row[3:],dtype=int) / int(row[2])
# name의 동과 다른지역의 데이터의 차의 제곱의 합.
# s값이 가장 작은 지역이 name 동과 가장 비슷한 인구구조 지역
s = np.sum((home - away) ** 2)
#s < mn : 다른지역의 오차합이 더작은지역 mn과 가장 가까운 지역
#name not in row[0] : name의 지역이 아닌 조건
if s < mn and name not in row[0] :
mn = s
#result_name : 현재까지 가장 오차가 적은 지역의 이름
result_name = re.sub('\\(\\\\d*\\)','',row[0])
#result : 현재까지 가장 오차가 적은 지역 데이터
result = away
#home : name 동의 데이터,
#home_name : name 동의 행정구역 이름
#result : data 중 가장 오차합이 작은 지역의 데이터
#result_name : 오차합이 작은 지역의 이름
plt.style.use('ggplot')
plt.figure(figsize=(10,5),dpi=100)
plt.rc('font', family='Malgun Gothic')
plt.title(name + '지역과 가장 비슷한 인구 구조를 가진 지역')
plt.plot(home, label = home_name)
plt.plot(result,label = result_name)
plt.legend()
plt.show()
📌
### pandas를 이용한 분석
import pandas as pd
df = pd.read_csv("data/age.csv")
# 오류발생.
# 'utf-8' codec can't decode byte 0xc7 in position 1: invalid continuation byte
'''
age.csv 파일 cp949 형태의 파일임. ANSI형태의 파일. EUC-KR, KSC5601..
cp949 형태 : 우리나라에서의 기본파일 해외에서는 UTF-8
csv모듈, open함수를 이용한 경우 기본인코딩이 cp949임.
MAC은 기본 인코등 방식이 UTF-8임.
이때까지 윈도우환경의 경우 기본인코딩이 cp949여서 에러가 나지 않은것.
맥의 경우 인코딩 설정 따로 해주어야 에러가 나지 않는다.
'''
import pandas as pd
# thousands="," : 숫자의 세자리 마다,를 제거하고 순수한 숫자로만 인식
# index_col=0 : 0번 컬럼을 인덱스로 설정
# 행정구역 컬럼이 인덱스로 설정됨
df = pd.read_csv("data/age.csv",encoding="cp949",thousands=",",index_col=0)
df.head()
df.info()
df.columns
# 컬럼명을 변경
col_name = ['총인구수','연령구간인구수']
for i in range(0,101) : # 0~100
col_name.append(str(i) + '세')
col_name
df.columns = col_name
df.columns
# df의 모든 컬럼들을 총인구수로 나누기. 비율로 저장
# (인구구조를 찾는것)
df = df.div(df["총인구수"],axis=0)
df.head()
# 총인구수, 연령구간인구수 컬럼 제거하기
del df["총인구수"],df["연령구간인구수"]
df.info()
df.count() # 해당 컬럼의 결측값이 아닌 데이터의 건수.
# 결측값을 0으로 치환
# fillna : 결측값을 다른값으로 치환
df.fillna(0,inplace=True) # 결측값을 0으로 치환
↑
코드 전치처리
# 지정한 지역과 가장 비슷한 인구구조를 갖는 지역 찾아 그래프로 출력
name = "역삼2동"
# df.index : 행정구역명
# df.index.str : 인덱스의 이름을 문자열로 변경
# df.index.str.contains() : 선택된 이름을 포함?
# 지정한 이름을 가진 레코드만 True
a = df.index.str.contains(name)
a
df2 = df[a]
df2 # 지정한 지역의 데이터
# row[0]에서 코드 삭제하기
names = list(df2.index)
names[0] = names[0][:names[0].find('(')]
df2.index = names
# a값을 제외한 다른데이터만 저장
b = list(map(lambda x : not x,a))
b
df3 = df[b]
mn = 1
for label, content in df3.T.items() :
# label : 컬럼명. 각각의 행정동명
# content : 행정동 데이터
# s : 지정된 지역과 현재데이터의 오차 합
s = sum((content - df2.iloc[0]) ** 2)
if s < mn :
mn = s
result = content
name = result.name
result.name = name[:name.find('(')] # row[0]에서 코드 삭제하기
df2.T.plot() # 지정된 데이터
result.plot(legend = result_name)
plt.legend()
'수업(국비지원) > Python' 카테고리의 다른 글
[Python] 중복된 데이터 처리 (0) | 2023.04.25 |
---|---|
[Python] 데이터 전처리 (0) | 2023.04.25 |
[Python] numpy 연산 (0) | 2023.04.25 |
[Python] numpy 행렬 (0) | 2023.04.25 |
[Python] 지도를 이용한 시각화2 (0) | 2023.04.25 |