
부동산에서 아파트의 가격이 얼마나 오르고 내렸는지를 확인하기 위해 주택매매가격 종합지수를 참고할 필요가 있다.
KB 부동산과 통계청 에서 이 지수를 관리하고 있는데, 우선 KB 부동산 데이터를 이용하여 부동산 가격의 등락을 확인해보고자 한다.
KB 부동산 에 접속하면 뉴스/자료실에 월간 KB주택가격동향 메뉴를 확인할 수 있다.
해당 페이지의 ★시계열 자료 2020년 4월 기준 (1986년 1월 부터) 라는 게시글에 시계열 데이터가 담긴 엑셀 파일을 확인할 수 있는데, 이를 다운로드 받는다.

참고로 주간 KB주택시장동향 메뉴의 시계열 자료를 확인하면, 다음과 같이 지역별 주간 등락률을 시각적으로 확인할 수 있다.

필요한 모듈을 임포트 한다.
import datetime
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
matplotlib 라이브러리를 이용하여 그래프를 그릴 때, 한글 사용이 가능하도록 한다.
font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
다음 코드는 다운로드 받은 엑셀 파일과, 내부 엑셀시트 이름을 전달하면 pandas DataFrame 을 반환하는 함수이다.
DataFrame 을 반환하기 전에 각 column, row 에 대해 전처리 과정을 거친다.
def get_house_price_index(path, sheet):
data = pd.read_excel(path, sheet_name=sheet, skiprows=1)
data = data.set_index('구분')
data = data.drop('Classification')
# reorganize columns
bignames = '서울 대구 부산 대전 광주 인천 울산 세종 경기 강원 충북 충남 전북 전남 경북 경남 제주도 6개광역시 5개광역시 수도권 기타지방 구분 전국'
bignames = bignames.split(' ')
big_col = list(data.columns)
small_col = list(data.iloc[0])
for num, small in enumerate(small_col):
if str(small) == 'nan':
small_col[num] = big_col[num]
check = num
while True:
if big_col[check] in bignames:
big_col[num] = big_col[check]
break
else:
check -= 1
data.columns = [big_col, small_col]
# reorganize indices
data = data[data.index.notnull()]
data.index.name = 'date'
new_index = []
for num, raw_index in enumerate(data.index):
raw_index = str(raw_index)
if raw_index.find('.') >= 0:
temp = raw_index.split('.')
if len(temp[0]) == 2:
new_index.append('19' + temp[0] + '.' + temp[1])
else:
new_index.append(raw_index)
else:
new_index.append(new_index[num-1].split('.')[0] + '.' + raw_index)
data.set_index(pd.to_datetime(new_index), inplace=True)
return data
위에서 구현한 get_house_price_index 함수를 호출하여, 주택매매가격 종합지수의 모든 데이터를 출력한 결과이다.
data = get_house_price_index('datasets/★(월간)KB주택가격동향_시계열(2020.04).xlsx', '매매종합')
print(data)
전국 서울 ... 경남 제주도 기타지방
전국 서울 강북 강북구 ... 통영 제주도 제주/\n서귀포 기타지방
1986-01-01 34.6561 30.0438 41.94 NaN ... NaN NaN NaN NaN
1986-02-01 34.6561 30.0438 41.8891 NaN ... NaN NaN NaN NaN
1986-03-01 34.708 30.0024 41.8891 NaN ... NaN NaN NaN NaN
1986-04-01 34.4486 29.8366 41.7366 NaN ... NaN NaN NaN NaN
1986-05-01 34.2929 29.588 41.2791 NaN ... NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ...
2019-12-01 100.222 102.56 102.275 103.256 ... NaN NaN 97.1319 97.5571
2020-01-01 100.576 103.056 102.687 103.382 ... NaN NaN 97.0367 97.5658
2020-02-01 100.948 103.417 103.006 103.488 ... NaN NaN 96.9613 97.5925
2020-03-01 101.511 103.905 103.403 103.332 ... NaN NaN 96.8012 97.6337
2020-04-01 101.744 104.072 103.577 103.194 ... NaN NaN 96.7289 97.6126
[412 rows x 186 columns]
위에서 생성한 데이터에서 강남, 강북, 수도권 지역만을 필터링하여 하나의 DataFrame으로 분리하였다.
df = pd.DataFrame()
df['강남'] = data['서울']['강남']
df['강북'] = data['서울']['강북']
df['수도권'] = data['수도권']['수도권']
2015년 1월 1일 이후의 등락률을 표본 데이터로 삼았다.
pct_change 함수 는 현재와 이전 데이터와의 percent 차이를 계산해주고, cumsum 함수 는 이들 간의 누적합을 계산해준다. 등락률의 누적합을 계산하여 각 지역별 차이를 확인하기 위한 목적이다.
df = df[df.index > datetime.datetime(2015, 1, 1)]
df = df.pct_change().cumsum()
그래프로 확인한 결과는 다음과 같다.
df.plot()
plt.grid()
plt.show()

확인 결과, 서울 강남 > 서울 강북 > 수도권 순으로 상승폭이 컸음을 알 수 있다.
추가적으로 3개 도시 뿐 아니라 모든 도시의 등락률도 확인해 보고자 한다.
2020년 4월 1일과 2015년 1월 1일 사이의 등락률을 계산하고, 데이터를 내림차순으로 정렬하였다.
아래의 분석 결과를 확인해보면 서울 강남구보다도 서울 영등포구, 경기 분당구와 같은 도시들의 상승률이 컸음을 알 수 있다.
base_date = datetime.datetime(2015, 1, 1)
target_date = datetime.datetime(2020, 4, 1)
data = data.loc[[base_date, target_date]]
data = data.T
data['result'] = (data[target_date] - data[base_date]) / data[base_date] * 100.0
data = data.dropna()
data = data['result'].sort_values(ascending=False)
for index in data.index:
print(index, '{:.2f}%'.format(data[index]))
('서울', '영등포구') 43.27%
('경기', '분당구') 43.01%
('서울', '강남구') 41.52%
('경기', '광명') 38.57%
('서울', '양천구') 34.08%
('서울', '서초구') 33.70%
('서울', '송파구') 33.11%
('서울', '동대문구') 32.20%
('서울', '강남') 31.09%
('서울', '노원구') 31.05%
('서울', '마포구') 30.82%
('경기', '성남') 30.36%
('서울', '성동구') 29.93%
('경기', '동안구') 28.39%
('서울', '강동구') 28.14%
('서울', '서울') 28.07%
('서울', '서대문구') 27.96%
('서울', '구로구') 27.96%
('서울', '용산구') 27.96%
('서울', '동작구') 27.45%
('서울', '성북구') 27.11%
('경기', '안양') 26.99%
('경기', '과천') 26.88%
('서울', '강서구') 25.77%
('경기', '수지구') 25.66%
('서울', '중구') 25.11%
('서울', '강북') 25.04%
('경기', '만안구') 24.69%
('경기', '영통구') 24.62%
('경기', '군포') 23.26%
('서울', '도봉구') 23.11%
('경기', '구리') 22.67%
('대구', '수성구') 22.14%
('서울', '금천구') 21.42%
('서울', '중랑구') 19.83%
('서울', '광진구') 19.76%
('수도권', '수도권') 19.70%
('광주', '광산구') 19.66%
('광주', '서구') 19.45%
('대전', '서구') 19.35%
('서울', '관악구') 18.28%
('경기', '덕양구') 18.17%
('경기', '부천') 17.50%
('경기', '수원') 17.37%
('서울', '종로구') 16.70%
('경기', '장안구') 16.54%
('서울', '은평구') 16.34%
('경기', '중원구') 16.15%
('대구', '동구') 15.92%
('대구', '중구') 15.53%
('광주', '광주') 15.35%
('경기', '용인') 15.31%
('대전', '유성구') 15.12%
('인천', '부평구') 15.12%
('경기', '기흥구') 15.08%
('부산', '해운대구') 15.07%
('대구', '서구') 14.98%
('서울', '강북구') 14.96%
('경기', '경기') 14.87%
('부산', '남구') 14.74%
('대전', '대전') 14.20%
('대전', '중구') 14.10%
('경기', '팔달구') 13.96%
('광주', '남구') 13.81%
('부산', '수영구') 13.47%
('대구', '대구') 13.14%
('인천', '연수구') 13.08%
('광주', '동구') 13.06%
('경기', '고양') 13.00%
('대구', '달서구') 12.82%
('경기', '수정구') 12.79%
('부산', '동래구') 12.76%
('경기', '권선구') 12.69%
('인천', '계양구') 12.57%
('전국', '전국') 12.34%
('경기', '김포') 12.30%
('제주도', '제주/\n서귀포') 11.74%
('인천', '인천') 11.60%
('대전', '동구') 11.57%
('인천', '서구') 11.37%
('인천', '미추홀구') 11.22%
('6개광역시', '6개광역시') 10.63%
('울산', '5개광역시\n(인천外)') 10.33%
('경기', '단원구') 10.21%
('광주', '북구') 10.15%
('경기', '남양주') 10.05%
('인천', '남동구') 9.91%
('대구', '남구') 9.88%
('경기', '일산동구') 9.60%
('경기', '의정부') 9.42%
('전남', '여수') 9.00%
('경기', '일산서구') 8.42%
('전남', '순천') 8.30%
('부산', '부산') 8.25%
('부산', '연제구') 8.21%
('세종', '세종') 7.56%
('경기', '안산') 7.45%
('대구', '북구') 7.42%
('전북', '익산') 6.89%
('부산', '서구') 6.79%
('경기', '시흥') 6.66%
('전남', '전남') 6.63%
('부산', '금정구') 6.57%
('경기', '파주') 6.22%
('경기', '화성') 6.08%
('부산', '부산진구') 6.04%
('부산', '사상구') 5.12%
('인천', '동구') 5.00%
('부산', '동구') 4.83%
('경기', '상록구') 4.82%
('부산', '사하구') 4.51%
('인천', '중구') 3.63%
('부산', '기장군') 3.15%
('울산', '남구') 2.97%
('대전', '대덕구') 2.87%
('부산', '북구') 2.84%
('부산', '중구') 2.66%
('전북', '덕진구') 2.61%
('부산', '영도구') 2.29%
('강원', '춘천') 1.79%
('강원', '강원') 1.78%
('대구', '달성군') 1.78%
('전남', '목포') 1.77%
('강원', '원주') 1.74%
('경남', '진주') 1.44%
('경기', '이천') 1.25%
('전북', '전주') 1.22%
('전북', '전북') 0.75%
('전북', '완산구') 0.11%
('충남', '논산') -0.75%
('충남', '공주') -1.03%
('경기', '처인구') -1.13%
('울산', '중구') -1.19%
('경북', '남구') -1.64%
('울산', '울주군') -1.76%
('기타지방', '기타지방') -2.77%
('경북', '경산') -2.85%
('울산', '울산') -2.98%
('경북', '포항') -3.97%
('충북', '충주') -4.32%
('경남', '마산회원구') -5.21%
('경기', '평택') -5.70%
('경북', '북구') -5.81%
('충남', '충남') -6.07%
('충남', '아산') -6.16%
('경남', '마산합포구') -6.32%
('충남', '동남구') -6.78%
('전북', '군산') -6.79%
('울산', '북구') -7.16%
('경북', '경북') -7.17%
('충북', '흥덕구') -7.39%
('충북', '충북') -7.48%
('경남', '경남') -7.62%
('충남', '천안') -8.09%
('충북', '청주') -8.42%
('경남', '김해') -8.85%
('충남', '서북구') -9.14%
('경남', '진해구') -9.44%
('충북', '상당구') -10.16%
('경남', '창원') -10.32%
('경남', '의창구') -11.69%
('울산', '동구') -13.13%
('경북', '구미') -14.19%
('경남', '성산구') -16.93%