오늘은 본격적인 데이터 분석에 앞서 데이터 파일의 입출력에 대한 내용과 공공데이터포털 API를 사용해서 데이터를 수집하는 방법을 실습해보았다.
‘경로/파일명.확장자’ 형태의 문자열을 인수로 지정‘C:\Users\Account\Documents\project\code’‘/Users/Acount/Documents/project/code’r'C:\Users’)| 구분 | 상세 내용 | 구분 | 상세 내용 |
|---|---|---|---|
os.getcwd() | 현재 작업 경로를 문자열로 반환 | os.path.exists(path) | 지정한 경로의 존재 여부를 True, False로 반환 |
os.chdir(path) | 작업 경로를 변경 | os.path.isfile(path) | 지정한 경로가 파일이면 True, 아니면 False |
os.mkdir(path) | 새 폴더를 생성 | os.path.isdir(path) | 지정한 경로가 폴더이면 True, 아니면 False |
os.rmdir(path) | 빈 폴더를 삭제(빈 폴더가 아니면 에러 발생) | os.path.abspath(path) | 지정한 경로에 대한 절대 경로를 반환 |
os.listdir(path) | 지정한 경로에 있는 폴더명과 파일명을 문자열 리스트로 반환 | shutil.copy(src, dst) | 파일을 복사 |
os.remove(path) | 지정한 파일을 삭제(폴더 지정 시 에러 발생) | shutil.copytree(src, dst) | 폴더에 있는 모든 파일과 하위 폴더를 통째로 복사 |
os.rename(src, dst) | 폴더명 또는 파일명 변경 | shutil.move(src, dst) | 파일을 옮김 |
os.path.join(*paths) | 여러 경로명을 하나로 결합 | shutil.rmtree(path) | 폴더에 있는 모든 파일과 하위 폴더를 통째로 삭제(사용X) |
os.getcwd()
os.chdir('..')
sorted() 사용os.chdir('../../data')
os.getcwd()
sorted(os.listdir())
files = []
for file in sorted(os.listdir()):
if 'xlsx' in file:
files.append(file)
[file for file in sorted(os.listdir()) if 'xlsx' in file]
files = [file for file in sorted(os.listdir()) if 'test' in file]
for file in files:
os.remove(file)
sheet_name : 시트의 인덱스 또는 이름을 지정usecols : 선택할 열의 정수 인덱스 도는 열이름을 리스트skiprows : 열이름 위로 생략할 행 개수를 지정thousands : 천 단위 구분자를 지정(문자열 → 숫자)dfs = pd.read_excel('APT_Price_Seoul_Split_2020~2024.xlsx',
sheet_name=None,
usecols=range(1,16),
skiprows=3,
thousands=','
)
ignore_index=True : 기존 데이터프레임의 인덱스를 무시하고 초기화df1 = pd.concat(dfs, ignore_index=True)
index=False : 인덱스 생략df1.to_excel('test.xlsx', index=False)
info()df1.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 231904 entries, 0 to 231903
# Data columns (total 15 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 거래금액 231904 non-null int64
# 1 지역코드 231904 non-null int64
# 2 아파트 231904 non-null object
# 3 시도명 231904 non-null object
# 4 시군구 231904 non-null object
# 5 법정동 231904 non-null object
# 6 지번 231904 non-null object
# 7 건축년도 231904 non-null int64
# 8 년 231904 non-null int64
# 9 월 231904 non-null int64
# 10 일 231904 non-null int64
# 11 등기일자 79535 non-null datetime64[ns]
# 12 매도자 56193 non-null object
# 13 전용면적 231904 non-null float64
# 14 층 231904 non-null int64
# dtypes: datetime64[ns](1), float64(1), int64(7), object(6)
# memory usage: 26.5+ MB
head() : 처음 5행 확인tail() : 마지막 5행 확인sample() : 무작위 5행 확인random_state 매개변수에 시드를 지정할 수 있음# 원하는 파일만 선택하여 리스트에 저장
files = [file for file in sorted(os.listdir()) if 'Split' in file and 'csv' in file]
with open() 사용with open(file = files[0], mode='rb') as file:
text = file.read()
chardet.detect(text[:100])
# {'encoding': 'EUC-KR', 'confidence': 0.99, 'language': 'Korean'}
chardet.detect(text)
# {'encoding': 'CP949', 'confidence': 0.99, 'language': 'Korean'}
pd.read_csv(files[0], encoding='CP949')
encoding : 인코딩 방식 지정(CP949, UTF-8 등)parse_dates : 날짜시간형으로 읽을 열이름을 리스트로 지정yyyy-mm-dd HH:MM:SS)일 때 정상 실행00:00:00 으로 자동 적용thousands : 천 단위 구분자를 지정(문자열 → 숫자)df2 =pd.DataFrame()
for file in files:
df = pd.read_csv(file,
encoding='CP949',
parse_dates=['등기일자'],
thousands=','
)
df2 = pd.concat([df2, df], ignore_index=True)
df2.to_csv('test.csv', index=False, sep=',', encoding='UTF-8')
DtypeWarning : 파일을 읽고 메모리에 저장할 때 저장해둔 데이터 타입이 섞여있음(결측)low_memory=False 속성(메모리 제한 해제) 적용으로 해결 가능df3 = pd.read_csv('test.csv')
# DtypeWarning: Columns (11,12) have mixed types
df3 = pd.read_csv('test.csv', low_memory=False)
df2.to_pickle('test.pkl')
df4 = pd.read_pickle('test.pkl')
pd.to_pickle([df1, df2, df3], filepath_or_buffer='test_all.pkl')
df1_1, df2_1, df3_1 = pd.read_pickle('test_all.pkl')
objs = pd.read_pickle('test_all.pkl')
len(objs) # 3
objs = {
'df1': df1,
'df2': df2,
'df3': df3
}
pd.to_pickle(objs, filepath_or_buffer='test_all.pkl')
dct = pd.read_pickle('test_all.pkl')
globals() : 전역 변수 목록을 보여줌update() : 딕셔너리에서 원소를 추가globals().update(dct)
import requests, xmltodict, json
from pprint import pprint
from tqdm.notebook import tqdm
import pandas as pd
requests : HTTP 요청(API 호출 등)xmltodict : XML → Python 딕셔너리 변환json : json → Python 딕셔너리 변환tqdm : 주피터 노트북용 진행도 표시줄pprint : 딕셔너리를 보기 좋게 출력URL = 'https://apis.data.go.kr/'
API_KEY = ''
query = {
'LAWD_CD': '11680',
'DEAL_YMD': '202512',
'serviceKey': API_KEY,
'numOfRows': 9999,
'pageNo': 1
}
res = requests.get(url=URL, params=query)
res.status_code # 200
res.headers
# {'Content-Type': 'application/xml;charset=utf-8', 'Date': 'Wed, 07 Jan 2026 11:59:45 GMT', 'Server': 'Apache',
# 'Set-Cookie': 'JSESSIONID=92CE385C24CC20B8BECB226BAB288EA1; Path=/oasis; Secure; HttpOnly',
# 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'X-Frame-Options': 'SAMEORIGIN', 'Transfer-Encoding': 'chunked'}
res.headers['content-type']
# 'application/xml;charset=utf-8'
data = xmltodict.parse(xml_input=res.text)
df = pd.DataFrame(data['response']['body']['items']['item'])
def apt_price(areaCd, ymonth, nrow=9999, page=1):
# url 주소 및 api 키
URL = 'https://apis.data.go.kr/'
API_KEY = ''
# 요청 변수
query = {
'LAWD_CD': areaCd,
'DEAL_YMD': ymonth,
'serviceKey': API_KEY,
'numOfRows': nrow,
'pageNo': page
}
# requests 가져오기
res = requests.get(url=URL, params=query)
# xml 데이터 추출
data = xmltodict.parse(xml_input=res.text)
# 데이터프레임으로 변환
df = pd.DataFrame(data['response']['body']['items']['item'])
return df
ymonths = [str(i) for i in range(202501, 202513)]
print(ymonths)
# ['202501', '202502', '202503', '202504', '202505', '202506', '202507', '202508', '202509', '202510', '202511', '202512']
dfs = pd.DataFrame()
for ymonth in tqdm(ymonths):
# ymonth를 순회하면서 df 생성
df = apt_price(areaCd='11680', ymonth=ymonth)
# 생성 된 df를 dfs에 병합
dfs = pd.concat([dfs, df], ignore_index=True)
이전 프로젝트를 진행하면서 조금씩 다뤘던 os와 공공데이터포털 API에 대해서 더 배워보고 싶었는데, 오늘 배울 수 있어서 정말 좋았고 재밌었다. 혼자 알아보면서 공부할 때는 어렵게만 느껴졌는데, 막상 배우니까 쉽게 느껴져서 다음에도 많이 활용할 수 있을 것 같다.