촉촉한초코칩

파이썬으로 시작하는 데이터 사이언스 - 5강 본문

Study/Big Data

파이썬으로 시작하는 데이터 사이언스 - 5강

햄친구베이컨 2023. 11. 22. 02:07
1. 국가통계포털 데이터셋 소개

 

KOSIS (국가통계포털) https://kosis.kr/statHtml/statHtml.do?orgId=101&tblId=DT_1KE10081&vw_cd=MT_ZTITLE&list_id=JF&seqNo=&lang_mode=ko&language=kor&obj_var_id=&itm_id=&conn_path=MT_ZTITLE

  • 국내통계 > 주제별통계
  • K-beauty 상품의 판매액을 알아보기 위해
    도소매 서비스 > 온라인쇼핑동향조사 > 국가(대륙)별/상품군별 온라인쇼핑 해외직접판매액 선택
    분기별, 년도별로 다운로드 받을 수 있다. 
    분기 선택 > 조회 > CSV 형태로 다운로드 

 

2. 데이터셋 로드하기

 

 

 

 

 

 

#필요한 라이브러리 가져오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

%matplotlib inline

#os 별로 다른 서체를 설정해준다.
import os
os.name
if os.name == "posix":
   sns.set(font="AppleGothic")
elif os.name == "nt":
   sns.set(font="Malgun Gothic")
   
#데이터 로드하기
#사이트 하단에 각 값이 어떤 것을 의미하는지 나와있다.
pd.read_csv("파일명", encoding="cp949")

#데이터 개수 세기
df_raw = pd.read_csv("파일명", encoding="cp949")
df_raw.shape

#국가(대륙)별 데이터가 몇개 있는지 
df_raw["국가(대륙)별"].value_counts()

#미국 데이터만 보기
df_raw[df_raw["국가(대륙)별"]=="미국"]

 

3. 데이터 전처리 - tidy data 만들기

 

#melt 함수 : 행에 있는 데이터를 열로 옮긴다.
#집계한 데이터를 tidy data 형식으로 만든다.
#id_vars : id값으로 사용할 열 지정
#value_vars : value로 들어가는 열 지정
#id_vars에 들어가지 않은 열들은 value_vars로 들어간다.
df_raw.melt(id_vars["국가(대륙)별", "상품군별", "판매유형별"])

#variable, value라는 column의 이름을 "기간", "백만원"으로 변경한다.
df = df_raw.melt(id_vars=["국가(대륙)별", "상품군별", "판매유형별"], var_name="기간", value_name="백만원")
df.shape

df.head()
df.info() #연도와 분기를 분리하고, 숫자로 변경해야 한다.

 

4. 데이터 전처리 - 문자열 분리하고 데이터 타입 변경하기

 

#기간에서 연도 분리하기
df["기간"]

#split()을 사용하면 공백으로 데이터를 분리한다. 
"2019 4/4 p)".split() #결과 : ['2019','4/4','p)']

#첫번째 인덱스만 가져온다.
"2019 4/4 p)".split()[0]

#데이터 타입을 확인하면 string 타입이라는 것을 알 수 있다.
type("2019 4/4 p)".split()[0])

#integer 형으로 변경한다.
int("2019 4/4 p)".split()[0])

#map은 안에 함수를 넣을 수 있다.
#x.split()한 데이터의 첫번째 인덱스 값을 integer 형으로 변경한다. 
df["기간"].map(lambda x: int(x.split()[0]))

#map을 사용하여 연도라는 열을 만든다.
df["연도"] = df["기간"].map(lambda x : int(x.split()[0]))
df.head()

#분기 열을 만든다.
#공백과 /을 기준으로 데이터를 split하여 4/4에 있는 4와 4를 분리한다.
"2019 4/4 p)".split()[1]).split("/")

#첫번째 인덱스 가져오기
"2019 4/4 p)".split()[1]).split("/")[0]

#분기라는 새로운 열에 해당 lambda 함수를 적용한다.
df["분기"] = df["기간"].map(lambda x : int(x.split()[1]).split("/")[0]))

#금액을 수치 데이터로 표현하기 위해 데이터 타입을 변경한다.
#2016년 이전 데이터는 결측치가 많고 -으로 기록되어 있다. -로 표시된 값은 결측치이므로 NaN으로 대치한다.
#numpy를 로드하지 않았으면 pandas 안에 있는 np.nan을 쓸 수 있다.
df["백만원"].replace("-", pd.np.nan)

#astype(float)을 활용하여 데이터를 float 데이터 형태로 확인할 수 있다.
#-은 NaN으로 변경하였고, 숫자는 소수점으로 변경하였다. 
#replace()한 값을 "백만원" 열에 덮어쓰기 한다. 
df["백만원"]= df["백만원"].replace("-", pd.np.nan).astype(float)


#필요 없는 데이터 제거하기
#값이 합계가 아닌 데이터만 집계하여 df을 다시 업데이트한다.
df = df[(df["국가(대륙)별"] != "합계") & (df["상품군별"] != "합계")].copy()

#결측치를 확인한다. 
#금액이 없는 데이터도 있다는 것을 참고한다. 
df.isnull().sum()

 

5. 전체 상품군별 데이터로 연도별 증가추세 시각화 하기

 

#전체 상품군 판매액 시각화
#NaN으로 표시된 결측치 데이터가 있으면 시각화가 잘 안나타날 수 있으므로 
#NaN으로 나타난 행의 데이터를 제거하고 시각화한다.

#판매유형별이 계인 데이터를 가져온다.
df_total = df[df["판매유형별"] == "계"].copy()
df_total.head()

#연도에 따른 판매액을 lineplot으로 그려본다.
sns.lineplot(data=df_total, x="연도", y="백만원")

#상품군 별로 다른 색상으로 표시한다.
#legend 값을 밖에 표시하는 소스코드를 stack overflow에서 가져온다.
sns.lineplot(data=df_total, x="연도", y="백만원", hue="상품군별")
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)

#relplot을 lineplot의 서브플롯을 그리기 위해 사용한다. 
#kind를 line으로 설정한다.
sns.relplot(data=df_total, x="연도", y="백만원", hue="상품군별", kind="line")

#상품군별로 색상을 다르게 하기 위해 col 옵션을 활용하고 한 행을 4개를 표시하기 위해 col_wrap 옵션을 사용한다.
sns.relplot(data=df_total, x="연도", y="백만원", hue="상품군별", kind="line", col="상품군별", col_wrap=4)

#화장품이 다른 상품군들에 비해 해외직접판매액이 꾸준히 증가하고 있다는 것을 알 수 있다. 
#다른 값들은 잘 안나타나므로 화장품을 빼고 확인해본다.
# ~을 사용하면 데이터가 반전된다. 상품군별이 화장품인 데이터만 빼고 df_sub 변수에 담는다.
df_sub = df_total[~df_total["상품군별"].isin(["화장품"])].copy()

#kind의 기본값이 scatter이므로 line으로 바꿔준다. 
#의류, 패션 상품도 많이 판매함을 알 수 있다. 
#가전 전자 통신기기와 음반비디오 악기 쪽도 성장세가 있음을 알 수 있다.
sns.relplot(data=df_sub, x="연도", y="백만원", hue="상품군별", col="상품군별", col_wrap=4, kind="line")

#의류, 패션 상품도 빼고 가전, 음반 쪽 판매가 두드러지게 나타난다.
df_sub = df_total[~df_total["상품군별"].isin(["화장품", "의류 및 패션관련 상품"])].copy()

 

6. 화장품 온라인 해외 직접 판매액 시각화

 

#분기별 화장품 판매액 데이터 시각화
#화장품 데이터를 가져오기 위해 boolean 식을 만든다.
df_total["상품군별"] == "화장품"

#상품군별이 화장품인 데이터를 가져온다.
#copy()로 복사해야 원본 데이터에 영향을 미치지 않는다.
df_cosmetic = df_total[df_total["상품군별"] == "화장품"].copy()

#어떤 값이 들어있는지 확인한다.
df_cosmetic["상품군별"].unique()

#시각화 그래프를 그려본다.
sns.lineplot(data=df_cosmetic, x="연도", y="백만원")

#분기별로 살펴본다.
plt.figure(figsize=(15, 4))
sns.lineplot(data=df_cosmetic, x="연도", y="백만원", hue="분기")

#연도가 아닌 기간으로 그래프를 그려본다.
#글씨가 겹쳐지지 않게 하기 위해 xticks()를 사용하여 글자를 회전시킨다.
plt.figure(figsize=(15,4))
plt.xticks(rotation=30)
sns.lineplot(data=df_cosmetic, x="기간", y="백만원")

#국가, 대륙 별로 한번 출력해보고 df_cosmetic 데이터 프레임을 살펴본다.
df_cosmetic.head()

#중국에서의 판매액이 가장 높은 것을 확인할 수 있다.
plt.figure(figsize=(15,4))
plt.xticks(rotation=30)
sns.lineplot(data=df_cosmetic, x="기간", y="국가(대륙)별")

#중국을 빼고 시각화 그래프를 그리면 아세안에서 최근 높은 판매량을 기록했음을 알 수 있다.
plt.figure(figsize=(15,4))
plt.xticks(rotation=30)
sns.lineplot(data=df_cosmetic[df_cosmetic["국가(대륙별)"] != "중국"], x="기간", y="국가(대륙)별")

#기간 별로 시각화를 한다.
#"계" 데이터를 빼고 그래프를 그리니 온라인 면세점이 성장하고 있다는 사실을 알 수 있다.
plt.figure(figsize=(15,4))
plt.xticks(rotation=30)
df_sub = df[df["판매유형별"] != "계"].copy()
sns.lineplot(data=df_sub, x="기간", y="백만원", hue="판매유형별")

#온라인 면세점도 빼고 시각화한다.
#면세점 이외에도 증가 추세를 볼 수 있다.
plt.figure(figsize=(15,4))
plt.xticks(rotation=30)
df_sub = df[(df["판매유형별"] != "계") & (df["판매유형별"] != "면세점")].copy()
sns.lineplot(data=df_sub, x="기간", y="백만원", hue="판매유형별", ci=None)

 

7. 패션 의류 온라인 해외 직접 판매액 시각화

 

#의류 데이터만 df_fashion 변수에 넣는다.
df_fashion = df[df["상품군별"] == "의류및 패션관련 상품"].copy()

#판매유형별이 계인 데이터를 df_fashion에 넣는다.
df_fashion = df[(df["상품군별"] == "의류 및 패션관련 상품") & (df["판매유형별"] == "계")].copy()

#기간별 금액 데이터를 시각화하고, 국가(대륙별)을 색상으로 표시한다.
#그래프를 그려본 꾸준히 증가하고 있음을 알 수 있다.(중국, 일본, 미국, 아세안)
plt.figure(figsize=(15, 4))
plt.xticks(rotation=30)
sns.lineplot(data=df_fashion, x="기간", y="백만원", hue="국가(대륙)별")

#계를 제거하고 그린다.
df_fashion2 = df[(df["상품군별"] == "의류 및 패션관련 상품") & (df["판매유형별"]!= "계")].copy()
plt.figure(figsize=(15, 4))
plt.xticks(rotation=30)
sns.lineplot(data=df_fashion2, x="기간", y="백만원", hue="판매유형별" ci=None)

 

8. 데이터 pivot table로 집계하고 heatmap 으로 표현하기

 

#패션 데이터만 따로 모아놓은 변수를 사용하여 데이터를 집계한다.
df_fashion

df_fashion.pivot_table?

#aggfunc 옵션의 기본값이 mean이기 때문에 평균값이 나온다.
df_fashion.pivot_table(index="국가(대륙)별", columns="연도", values="백만원")

#aggfunc의 값을 sum으로 하여 합계값을 알아본다.
df_fashion.pivot_table(index="국가(대륙)별", columns="연도", values="백만원", aggfunc="sum")

#계만 있기 때문에 가공없이 그대로 sum을 사용하면 연도별 합계를 알아볼 수 있다.
df_fashion["판매유형별"].value_counts()
result = df_fashion.pivot_table(index="국가(대륙)별", columns="연도", values="백만원", aggfunc="sum")

#heatmap을 그려보면 온라인에서 판매가 많이 일어난다는 것을 알 수 있다.
#vmax는 시각화 할 때 나타내는 최대값이다. vmax와 vmin의 기본값을 그대로 사용해본다.
sns.heatmap(result)

#cmap 옵션으로 색상을 변경한다.
sns.heatmap(result, cmap = "Blues_r")

#annot 옵션으로 수치를 표시한다.
sns.heatmap(result, cmap = "Blues_r", annot=True)

#fmt 옵션으로 소수점 없이 float 형의 숫자를 나타낼 수 있다.
#plt.figure()로 그래프의 사이즈를 재설정한다.
plt.figure(figsize=(10, 6))
#연도, 대륙 별로 같이 볼 수 있다. pivot table로는 분포를 보기 어려운데 heatmap에서는 분포를 색상으로 편하게 볼 수 있다.
sns.heatmap(result, cmap="Blues_r", annot=True, fmt=".0f")

 

9. 전체상품군별 시각화

 

#판매유형별이 계인 데이터만 모인 데이터프레임을 활용한다.
df_total

#x축에 연도, y축에 금액을 넣는다.
#그래프를 보면 판매액이 꾸준히 증가했다는 사실을 알 수 있고, 신뢰구간도 연도에 따라 계속 길어진다.
#estimator라는 옵션은 기본으로 mean(평균) 값을 구한다.
sns.barplot(data=df_total, x="연도", y="백만원")

plt.figure(figsize=(15, 4))
sns.lineplot(data=df_total, x="연도", y="백만원", hue="국가(대륙)별")

#연도별 판매액을 "상품군별"로 다른색상으로 표현한다.
#legend 그래프를 밖에 그리기 위해 plt.lengend() 함수를 사용한다.
#bbox_to_anchor를 변경하면 그래프와 범례 사이 간격을 조절할 수 있다.
#그래프의 가장 위에 있는 데이터는 화장품이다.
plt.figure(figsize=(15, 4))
sns.lineplot(data=df_total, x="연도", y="백만원", hue="상품군별")
plt.legend(bbox_to_anchor=(1.02, 1), loc=2, borderaxespad=0,)