본문 바로가기
파이썬으로 부동산 매매가 조회기 만들기

파이썬으로 부동산 매매가 조회기 만들기 - 4. 라이브러리 이용해서 한 번 추출해보고, 필요한 컬럼만 따로 서울 아파트 매매가 조회해보기

by 유티끌 2023. 1. 7.

파이썬으로 부동산 매매가 조회기 만들기 - 4. 라이브러리 이용해서 한 번 추출해보고, 필요한 컬럼만 따로 서울 아파트 매매가 조회해보기

저번 포스트에서는 지역 구분별 코드를 컨버팅해주는 클래스를 만들어보았습니다. 이번 포스트에서는 일단 라이브러리를 이용해서 추출을 한다음에 어떤 컬럼이 필요한지, 필요없는지, 추가해야할 데이터는 무엇이 있을지 생각해보고 추가해서 정제한다음, 대표적으로 서울 아파트 매매가를 조회해보겠습니다.

라이브러리 이용해서 한 번 추출해보기

일단 라이브러리를 이용해서 결과물이 어떻게 나오는지 한 번 보겠습니다. 저번 포스트에서 말씀드린 것 처럼, 이번에는 테스트를 위해서 주피터노트북을 써서 직접 해보겠습니다. 주피터 서버를 띄우고 실행하는거다보니 조금 느린 것 같기도 하네요.

https://github.com/WooilJeong/PublicDataReader/blob/main/assets/docs/portal.md#%EA%B5%AD%ED%86%A0%EA%B5%90%ED%86%B5%EB%B6%80-%EC%8B%A4%EA%B1%B0%EB%9E%98%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C-%EC%84%9C%EB%B9%84%EC%8A%A4

라이브러리 제작자분께서 md파일을 잘 만들어주셔서... 잘 이용했습니다.
제가 원하는건 특정 월의 매매데이터라서, read_data() 메소드를 이용해보겠습니다. 파라미터로는 매물의 종류, 거래유형, 시군구코드, 거래가 발생한 연도와 달을 넘겨주고 실행해봅니다.

null

그러면 아래와 같이 결과값이 출력됩니다. 일단 print문으로 에러가 있는 api들에 대해 알려주네요. 에러가 있는 서비스들은 따로 제가 조회신청을 하지 않았기 때문에 에러출력되는 것이 당연합니다.

아래는 예시대로 조회한 데이터들이 나옵니다. 데이터들은 판다스의 데이터프레임(DataFrame)으로 변환되어 나옵니다.

null

  • 지역코드
  • 도로명
  • 법정동
  • 지번
  • 아파트
  • 건축년도
  • 전용면적
  • 거래금액 (만원단위)
  • 도로명건물본번호코드
  • 도로명건물부번호코드
  • 도로명시군구코드
  • 도로명일련번호코드
  • 도로명지상지하코드
  • 도로명코드
  • 법정동본번코드
  • 법정동부번코드
  • 법정동시군구코드
  • 법정동지번코드
  • 일련번호
  • 거래유형
  • 중개사소재지
  • 해제사유발생일
  • 해제여부

전체 컬럼은 위와 같습니다. 꽤 많기도하고... 숫자코드만 있어서 얼핏보면 이게 뭘 의미하는지 모르는 내용들도 많습니다. 그래서 필요한 컬럼들은 제외하고 뺄껀 빼주고, 여기서 추가되어야할 컬럼이 있으면 추가작업을 해주어야합니다.


서울아파트 매매가 조회해보기

일단 처음으로는 서울 모든 구의 아파트 매매가를 조회해보는 것으로 시작하겠습니다.
일단 property 폴더 하위에 extract_data 폴더를 만들고, 다시 extract.py 만들고, 필요한 메소드들을 정의하기 시작했습니다.

라이브러리를 이용한 API연결

일단 파일의 제일 윗부분에는 필요한 다른 파일들을 import하고, 컨버터의 객체생성과 함께 API연결을 선언합니다.

from property.const.district_converter import DistrictConverter
from config.api_key import PUBLIC_DATA_PORTAL
import pandas as pd
import PublicDataReader as pdr

converter = DistrictConverter()
API = pdr.Transaction(PUBLIC_DATA_PORTAL, debug=False)

데이터 조회 메소드 만들기

이어서 데이터를 조회할 메소드를 별도로 만듭니다. 이제와서 생각해보니 이걸 왜 별도로 뺐을까 하는 생각이 들긴 하네요...?

def get_data_from_portal(proudct, transaction, sigungu_code, year_month):
    return API.read_data(proudct, transaction, sigungu_code, year_month)

전용면적 평수 계산 메소드 만들기

위에서 조회하면 나오는 컬럼들을 보니 전용면적이 있는데, 이것이 제곱미터 기준이라 조금 헷갈린다 싶어서, 평수로 따로 만드는 메소드를 만들었습니다.

1평은 3.3제곱미터이므로, 전용면적 컬럼의 데이터를 3.3으로 나누고, 소숫점 둘째자리에서 반올림하여 소숫점 아래 첫째자리까지 출력되도록 합니다.

def caculate_column_data(df: pd.DataFrame):
    df["전용면적(평)"] = round(df["전용면적"] / 3.3, 1)

    return df

입력받은 시군구 리스트에 대해서 매매가 조회하는 메소드 만들기

이전 포스트와, 본 포스트 상단에 라이브러리로 넘기는 파라미터에서 보이듯이, 조회는 시군구 코드를 기준으로 조회하는데요 조회하고자하는 시군구가 여러개 일 수 있으므로, 시군구 데이터를 리스트로 받아 반복문을 돌리며 조회하는 메소드를 만듭니다.

이 때, API를 조회한 데이터에는 이것이 어떤 시/도의, 어떤 시군구의 데이터인지는 알 수 없습니다. 표시되는 것은 도로명과 읍면동 단위의 데이터만 한글로 나옵니다. (아마도 시군구코드를 넣어서 조회하는 것으로 보아, 조회할 때 이미 어떤 지역인지를 콕 찝어서 조회한다는 유저시나리오를 바탕으로 설계되어있는 것 같습니다.)

따라서, 우리가 결과물을 받아서 어디 데이터인지를 알기 위해서는 시/도 이름과, 시군구이름도 같이 표기되어야 알기 쉽습니다.

def get_data_using_sigungu_list(si_do_name, sigungu_list: list, product, transaction, year_month):
    df = pd.DataFrame()

파라미터로 시/도 이름, 시군구 데이터가 담긴 리스트, 매물종류, 거래종류, 거래년월 6자리를 받습니다. 이후 시군구리스트에 대해 반복문을 돌아가며 조회를 시작합니다.

    for sigungu in sigungu_list:
        data = get_data_from_portal(product, transaction, sigungu["sigungu_code"], year_month)
        data["시도"] = si_do_name
        data["시군구"] = sigungu["sigungu_name"]
        df = pd.concat([data, df])

조회한 데이터 data 에 대해, 위에서 말씀드린대로 시도 이름과 시군구 이름이 기재된 컬럼으로 생성해줍니다. sigungu_list 에 데이터 하나하나에는 sigungu_code, sigungu_name, eup_myeon_dong 데이터가 json형태로 들어있습니다. 본 시리즈의 2번째 포스트(지역구분별 코드 먼저 준비하기) 를 확인해주세요.

data["시군구"] = sigungu["sigungu_name"]

이렇게 시군구 json객체 하나하나에서 시군구이름을 뽑아 컬럼을 하나 만들어줍니다. 그 후에는 기존에 만들었던 시군구 데이터에, 바로 아래에 추가로 데이터를 이어붙여줍니다.

df = pd.concat([data, df])

이렇게해서 서울의 모든 구의 매매데이터를 하나하나 붙여나갑니다.

이 후에, 아까 위에서 만든 전용면적(평) 계산 메소드를 호출해줍니다.
df = caculate_column_data(df)

그러고 마지막으로 컬럼이름을 재정의해주고, 추출한 매매데이터를 리턴합니다. 저는 개인적으로 년, 월, 일 컬럼이 조금 알기 어렵다고 생각해서 아래와 같이 수정했습니다.

    df.rename(columns={"년": "거래년도",
                       "월": "거래월",
                       "일": "거래일"
                       },
              inplace=True)

    return df

본 메소드의 전체 코드는 아래와 같습니다.

def get_data_using_sigungu_list(si_do_name, sigungu_list: list, product, transaction, year_month):
    df = pd.DataFrame()

    for sigungu in sigungu_list:
        data = get_data_from_portal(product, transaction, sigungu["sigungu_code"], year_month)
        data["시도"] = si_do_name
        data["시군구"] = sigungu["sigungu_name"]
        df = pd.concat([data, df])

    df = caculate_column_data(df)

    df.rename(columns={"년": "거래년도",
                       "월": "거래월",
                       "일": "거래일"
                       },
              inplace=True)

    return df

서울 데이터만 조회하는 메소드 만들기

입력받은 시군구 리스트를 대상으로 매매데이터를 조회하여 리턴하는 메소드가 완성되었습니다. 그럼 이제 어느 시/도의 시군구를 파라미터로 넘겨줘야하냐, 이게 남았습니다.

저는 이번 시리즈 예시에서 일단 서울 데이터만 조회하는 메소드를 만들고 있어서, 서울 시도코드만 따로 추출하는 메소드를 만들어봅니다.

def get_seoul_data(product, transaction, year_month):
    seoul_code = converter.get_si_do_code("서울")
    seoul_name = converter.get_si_do_name("서울")
    sigungu_list = converter.get_sigungu(seoul_code)

    df = get_data_using_sigungu_list(seoul_name, sigungu_list, product, transaction, year_month)

여기에, 마지막으로 인덱스를 리셋해주고, 컬럼들을 제가 원하는 컬럼만으로 간추립니다.

return df.reset_index().reindex(columns=header)

제가 원하는 컬럼목록은 아래와 같습니다.

header = [
    "시도",
    "시군구",
    "법정동",
    "도로명",
    "지번",
    "아파트",
    "건축년도",
    "전용면적",
    "전용면적(평)",
    "거래년도",
    "거래월",
    "거래일",
    "거래금액",
    "일련번호",
    "거래유형",
    "중개사소재지",
    "해제여부",
    "해제사유발생일"

]

이렇게해서 extract.py의 내용이 일단 완료되었습니다. 전체 코드는 아래와 같습니다.

from property.const.district_converter import DistrictConverter
from config.api_key import PUBLIC_DATA_PORTAL
import pandas as pd
import PublicDataReader as pdr

converter = DistrictConverter()
API = pdr.Transaction(PUBLIC_DATA_PORTAL, debug=False)

header = [
    "시도",
    "시군구",
    "법정동",
    "도로명",
    "지번",
    "아파트",
    "건축년도",
    "전용면적",
    "전용면적(평)",
    "거래년",
    "거래월",
    "거래일",
    "거래금액",
    "일련번호",
    "거래유형",
    "중개사소재지",
    "해제여부",
    "해제사유발생일"

]


def get_seoul_data(product, transaction, year_month):
    seoul_code = converter.get_si_do_code("서울")
    seoul_name = converter.get_si_do_name("서울")
    sigungu_list = converter.get_sigungu(seoul_code)

    df = get_data_using_sigungu_list(seoul_name, sigungu_list, product, transaction, year_month)

    return df.reset_index().reindex(columns=header)


def get_data_using_sigungu_list(si_do_name, sigungu_list: list, product, transaction, year_month):
    df = pd.DataFrame()

    for sigungu in sigungu_list:
        data = get_data_from_portal(product, transaction, sigungu["sigungu_code"], year_month)
        data["시도"] = si_do_name
        data["시군구"] = sigungu["sigungu_name"]
        df = pd.concat([data, df])

    df = caculate_column_data(df)

    df.rename(columns={"년": "거래년도",
                       "월": "거래월",
                       "일": "거래일"
                       },
              inplace=True)

    return df


def caculate_column_data(df: pd.DataFrame):
    df["전용면적(평)"] = round(df["전용면적"] / 3.3, 1)

    return df


def get_data_from_portal(proudct, transaction, sigungu_code, year_month):
    return API.read_data(proudct, transaction, sigungu_code, year_month)

주피터 파일에서 만든 메소드를 이용해서 매매가 구해보기

이제, 테스트용 주피터 파일에서, 서울 매매데이터만 구해봅니다.

null

그러면 아래와 같이 제가 원하는 데이터만 보기좋게 딱 나옵니다.
데이터가 700개여서, 서울의 모든 구의 아파트 매매데이터가 다 나온 것 같네요.

null


이렇게 서울 아파트 매매 데이터를 구해보았습니다. 위에 파라미터를 아파트 로 넣었는데, 연립/다세대 매매 데이터 API에 대한 신청도 해놓으셨다면, 파라미터로 연립/다세대 를 넣으셔서 이른바 빌라 매매 데이터도 구해볼 수 있습니다.

다음 포스트에서는 서울 이외의 시도, 시군구에 대한 매매데이터를 구하는 메소드를 만들어봅니다.

끝!

반응형

댓글