각 코드 셀의 지시사항대로 2022년 서울 아파트 거래 데이터를 분석해보도록 하겠습니다.
import pandas as pd
import numpy as np
import pandas as pd
df = pd.read_csv('seoul_apart_2022.csv')
df
print(type(df))
df.shape
df.info() 로도 가능하다.
df에서 사용하지 않을 특정 컬럼을 제거하세요.drop을 활용해서 데이터 분석 과정에서 활용하기 어려운 컬럼들을 삭제합니다.df에 적용이 되어야 합니다.df = df.drop(["해제사유발생일", "중개사소재지", "번지", "본번", "부번", "도로명", "거래유형"], axis=1)
df
df = df.rename(columns = {'전용면적(㎡)' : '전용면적'})
df
# 시군구 분리하기
df["구"] = df["시군구"].apply(lambda x: x.split(" ")[1])
df["동"] = df["시군구"].apply(lambda x: x.split(" ")[2])
df
df['구'] = df['시군구'].apply(lambda e: e.split()[1])
이렇게 해도 사실 서울특별시 강남구 개포동 이렇게 인덱스별로 저장 가능
# 면적에 따라 아파트 유형을 분류하는 함수
def category(e):
# "전용면적"이 60 이하면 **소형**, 60보다 크고 85 이하면 **중형**, 85보다 크고 102 이하면 **중대형**, 102보다 크면 **대형**으로 분류
if e <= 60:
return "소형"
elif e > 60 and e <= 85:
return "중형"
elif e > 85 and e <= 102:
return "중대형"
else:
return "대형"
df["유형"] = df["전용면적"].apply(category)
df
df["계약일"] = df["계약년월"].astype(str) + "" + df["계약일"].astype(str)
df["계약일"] = pd.to_datetime(df["계약일"], format='%Y%m%d')
df
사실 astype로 형변화만 해주면 됨 +""+는 없어도 된다..
datetime으로 변경되었습니다. 이제 계약일 데이터를 활용해 "계약월"과 "계약요일" 컬럼을 생성해보겠습니다.df['계약월'] = df['계약일'].dt.month
df['계약요일'] = df['계약일'].dt.dayofweek
week_map = {0:"월", 1:"화", 2:"수", 3:"목", 4:"금", 5:"토", 6:"일"}
df['계약요일'] = df['계약요일'].map(week_map)
df
좀더 간결한 코드문
df['계약월'] = df['계약일'].dt.month
df['계약요일'] = df['계약일'].dt.dayofweek
df['계약요일'] = df['계약요일'].map({0: '월', 1: '화', 2: '수', 3: '목', 4: '금', 5: '토', 6: '일'})
df
부동산 거래 데이터에서 가장 중요한 데이터는 "거래금액(만원)"입니다. 이 거래금액을 활용하여 정렬을 하거나 다양한 통계값을 계산할 수 있습니다.
df.isna().sum()
"거래금액(만원)" 컬럼에 33개의 결측치가 있습니다. 거래금액은 데이터 분석에서 굉장히 중요한 정보이기 때문에 거래금액 정보가 없는 데이터는 사용할 수 없고, 다른 통계값으로 채워넣기에도 좋지 않습니다.
마침 데이터가 12000개가 넘어서 꽤 많기 때문에, 이번에는 "거래금액(만원)"컬럼에 결측치가 있는 데이터는 아예 삭제해버리도록 하겠습니다.
df에서 "거래금액(만원)"컬럼에 결측치가 존재하는 데이터를 삭제하세요.dropna를 활용해서 "거래금액(만원)" 컬럼에 결측치가 존재하는 아파트 거래 데이터를 삭제하세요.dropna의 ignore_index를 올바르게 설정하여 인덱스를 초기화해주어야 합니다.df = df.dropna(subset=["거래금액(만원)"], ignore_index=True)
df.isna().sum()
df.info()
데이터가 33개 줄어들기는 했지만, 결측치가 있는 데이터가 삭제되었습니다.
info를 통해 데이터의 정보를 다시 확인해보면 "거래금액(만원)"컬럼의 경우 데이터타입이 object인 것을 확인할 수 있습니다.
df["거래금액(만원)"] = df["거래금액(만원)"].str.replace(',','').astype(int)
df
아래처럼 해도 큰 차이는 없다.
df['거래금액(만원)'] = df['거래금액(만원)'].str.replace(',', '')
df['거래금액(만원)'] = pd.to_numeric(df['거래금액(만원)'])
df.info()
"거래금액(만원)" 컬럼의 데이터 타입이 정수형으로 바뀐 것을 확인할 수 있습니다.
print(df.sort_values("거래금액(만원)", ascending=False).head(10))
print(df["거래금액(만원)"].mean())
print(df["거래금액(만원)"].median())
아파트의 거래금액 자체도 중요하지만 크기에 따른 가격 또한 매우 중요한 지표입니다.
"전용면적"컬럼의 단위는 제곱미터로, 이는 국제 표준 규격이지만 우리에게는 평 단위가 조금 더 익숙합니다.
round(값, 자리수) 반올림 함수를 활용하여, "전용면적" 컬럼을 3.3으로 나눈 후, 소수점 둘째자리까지 반올림하여 덮어쓰기를 하세요.df["전용면적"] = (df["전용면적"] / 3.3).round(2)
df = df.rename(columns= {"전용면적" : "전용면적(평)"})
다음과 같이 해도 동일함
df['전용면적'] = round(df['전용면적'] / 3.3, 2)
df = df.rename(columns={'전용면적' : '전용면적(평)'})
df.head()
df에 "평당금액" 컬럼을 생성하세요.df에 "평당금액" 컬럼을 생성하세요.df["평당금액"] = (df["거래금액(만원)"] / df["전용면적(평)"]).round(2)
df
다음과 같이 해도 됨
df['평당금액'] = round(df['거래금액(만원)'] / df['전용면적(평)'], 2)
df.head()
print(df.sort_values("평당금액", ascending=False).head())
head(10)으로 해도 동일한 결과
앞서 거래금액을 기준으로 정렬했던결과 많이 다른 결과를 얻을 수 있습니다. 이러한 결과를 부동산 도메인 지식과 함께 활용한다면 유용한 분석이 이루어질 수 있을 것입니다. 이렇게 새로운 지표로 이루어진 컬럼을 생성하는 것은 데이터 분석 과정에서 매우 중요합니다.
print(df.groupby("구")["평당금액"].mean())
*groupby와 "구", "동" 컬럼을 활용하여 서초구의 각 동별 평당금액 평균값을 구할 수 있습니다.
df_grouped = df[df["구"] == "서초구"][["동","평당금액"]] # - "구" 컬럼을 활용하여 "구" 중에서 "서초구"의 각 동별 평당금액의 평균값을 df_grouped 변수에 저장하세요.
# - 위 변수를 활용하여 "평당금액"의 평균값이 2번째로 높은 동의 "이름"을 추출하여 출력하세요.
filtered_df = df_grouped.groupby("동")[["평당금액"]].mean()# 데이터 프레임화
# print(filtered_df)
filtered_df = filtered_df.sort_values("평당금액", ascending=False)
# print(filtered_df)
filtered_df = filtered_df.reset_index()
print(filtered_df.iloc[1]["동"])
# print(filtered_df.index[1]) # 주석처리하고 위 방식대로 해도 됨
좀더 간결한 풀이
df_grouped = df[df['구'] == '서초구'].groupby('동')[['평당금액']].mean()
df_grouped.sort_values('평당금액', ascending=False).iloc[1].name