촉촉한초코칩

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

Study/Big Data

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

햄친구베이컨 2023. 10. 21. 17:49
1. 공공데이터 포털 및 분석할 데이터셋 소개

 

공공데이터를 찾는 방법을 이해하고, 분석할 데이터셋을 알아본다. https://www.data.go.kr/

부스트코스3.ipynb
7.64MB
부스트코스3.py
0.01MB

https://colab.research.google.com/drive/1_qEsqr_h7P-1nz9IGYpYrCQUw1gRPB_S 연습하기

 

2. 공공데이터 로드하고 데이터 미리보기

 

  • read_csv() : csv 파일 불러오기
  • shape : 데이터 개수 (행, 열)
  • head()/tail() : 미리보기/마지막에 있는 데이터 불러오기
  • info() : 데이터 요약(정보)
  • columns : 컬럼명만 출력하기
  • dtypes : 데이터 타입 보기

 

3. 결측치 다루기

 

  • isnull() : 데이터가 null 값인지 아닌지 확인  
    true > null, false > null 아님
  • isnull().sum() : 칼럼마다 null값이 몇 개인지 세어준다.
  • plot()/plot.bar()/plot.harh() : 그래프 
    barh() : 세로 막대형 그래프
    rot : 글자들이 회전하여 표시된다.
  • reset_index : 데이터프레임으로 만들기
  • columns() : 새로운 칼럼명 지정 
  • sort_values() : 칼럼 정렬 (결측치만 보기)
    by로 기준 column을 설정하고 ascending으로 오름차순/내림차순 정렬을 지정한다. 
  • NaN : Not a Number 결측치 의미 
  • drop() : 칼럼 삭제
  • axis
    0 : 행, 1 : 열
  • tolist() : column명 리스트화하기 

 

4. 수치 데이터 요약하기 - 기술통계 값 보기

 

평균값

#데이터 타입
df.dtypes

#수치형 데이터 평균 구하기
df["위도"].mean()

 

중앙값

#중앙값 구하기
df.["위도"].median()

 

최댓값

df["위도"].max()

 

최솟값

df["위도"].min()

 

갯수

df["위도"].count()

 

기초통계값 요약하기 - describe

: 데이터를 요약할 수 있다. 기본적으로 수치형 데이터를 요약해서 보여준다.
데이터 갯수, 평균, 표준편차, 최솟값, 1사분위수(25%), 2사분위수(50%), 3사분위수(75%), 최댓값

#요약하기
df["위도"].describe()

#2개의 컬럼을 describe로 요약한다.
#2개 이상을 가져올 때는 하나로 묶어서 DataFrame으로 출력하기
df[["위도","경도"]].describe()

#describe로 문자열 데이터타입 요약하기
df.describe(include="object")

#describe로 수치형 데이터만 요약하기
df.describe(include="number")

#모든 데이터 요약하기
df.describe(include="all")
  • 결측치는 요약하지 않는다.
  • 이때 top은 가장 높은 빈도로 저장된 데이터를 의미한다. 
  • freq는 그 데이터의 빈도수를 표시한다.

 

5. 문자열 데이터 요약하기 - pandas 로 시각화 하기

 

중복제거한 값 보기 > unique()
문자형 데이터타입으로 요약하면 unique 값이 나온다.
데이터의 개수를 출력하려면 nuique() 사용한다. 

#상권업종대분류명에서 중복 제거하기
df["상권업종대분류명"].unique()

#상권업종대분류명 내 데이터의 개수 출력
df["상권업종대분류명"].nuique()

이때 nuique 대신 len을 사용할 수도 있다.

len(df["상권업종소분류명"].unique()

 

그룹화된 요약값 보기 : value_counts()
카테고리 형태의 데이터 갯수를 세어볼 수 있다.

#시도명을 기준으로 데이터가 몇 개 있는지 출력
city = df["시도명"].value_counts()

#normalize=True 옵션을 사용하면 비율을 구할 수 있다.
city_normalize = df["시도명"].value_counts(normalize=True)

#막대그래프로 표현하기 > Pandas의 plot() 사용
city.plot.barh()

#파이 그래프 그리기 > plot.pie()
city.plot.pie(figsize=(7,7))
city_normalize.plot.pie(figsize=(7,7))

 

6. 데이터 요약하기 - seaborn 으로 빈도수 시각화 하기

 

#seaborn의 countplot으로 그려보기
c = sns.countplot(data=df, y="시도명")

#상권업종대분류명으로 갯수 세어보기
df["상권업종대분류명"].value_counts()

#normalize=True 사용해서 비율 구하기
n = df["상권업종대분류명"].value_counts(normalize=True)

#plot.bar() 사용해서 막대그래프 그리기
#rot : rotation, 얼만큼 글자를 회전시킬 것인지
c.plot.bar(rot=0)

#plot.pie() 사용해서 파이그래프 그려보기
n.plot.pie()

#상권업종소분류명에 대한 그룹화 된 값을 카운트 한다.
e = df["상권업종소분류명"].value_counts()

#상권업종소분류명으로 갯수 세워보기
#plot.bar() 사용해서 막대그래프 그리기
#grid : 격자
e.plot.barh(figsize=(7,8), grid=True)

 

7. 원하는 데이터만 따로 추출해 오기 - 데이터 색인하기

 

#상권업종중분류명이 약국/한약방인 데이터 가져와서 df_medical 변수에 담기
#head()를 통해 미리보기한다. > 특정 숫자를 지정하면 숫자만큼 가져온다.
df_medical = df[df["상권업종중분류명"] == "약국/한약방"].copy()
df_medical.head()

#상권업종대분류명에서 의료만 가져온다.
#df.loc를 사용하면 행, 열을 함께 가져올 수 있다. 
#df.loc를 통해 상권업종중분류명만 가져온다.
#가져온 결과를 value_counts를 통해 중분류의 개수를 세어본다.
df.loc[df["상권업종대분류명"] == "의료", "상권업종중분류명"].value_counts()

#첫번째 코드처럼 나눠서 쓸 수도 있다.
m = df["상권업종대분류명"] == "의료"
df.loc[m, "상권업종중분류명"].value_counts()

#유사의료업만 따로 모아본다.
df[df["상권업종중분류명"] == "유사의료업"].shape

#상호명을 그룹화해서 개수를 세어본다.
#value_counts를 사용해서 상위 10개를 출력한다.
df["상호명"].value_counts().head(10)

#유사의료업만 df_medi 변수에 담는다.
#df_medi 변수에서 상호명으로 개수를 세어본다.
#가장 많은 상호 10개를 출력한다.
df_medi = df[df["상권업종중분류명"] == "유사의료업"]
df_medi["상호명"].value_counts().head(10)

 

여러 조건으로 색인하기

#상권업종소분류명이 약국인 것과, 시도명이 서울특별시인 데이터만 가져온다.
df_seoul_drug = df[(df["상권업종소분류명"] == "약국") & (df["시도명"] == "서울특별시")]

 

8. 텍스트 데이터 전처리하기

 

#구별로 보기
#위에서 색인한 데이터로 "시군구명"으로 그룹화해서 개수 세어보기
#구별로 약국이 몇 개 있는지 확인한다.
c = df_seoul_drug["시군구명"].value_counts()

#normalize=True를 통해 비율 구해보기
n.df_seoul_drug["시군구명"].value_counts(normalize=True)

#위에서 구한 결과를 판다스의 plot.bar()를 활용해 막대그래프로 보기
c.plot.bar()

#상권업종소분류명이 종합병원인 것과, 시도명이 서울특별시인 데이터만 가져온다.
#결과를 df_seoul_hospital에 할당해서 재사용한다.
df_seoul_hospital = df[(df["상권업종소분류명"] == "종합병원") &  (df["시도명"] == "서울특별시")].copy
#copy하지 않으면 df_seoul_hospital 내용이 변경되면 df 내용도 변경된다.

#시군구명으로 그룹화해서 구별로 종합병원의 수를 세어본다.
df_seoul_hospital["시군구명"].value_counts()

 

텍스트 데이터 색인하기

#색인하기 전에 상호명이 종합병원이 아닌 데이터를 찾는다.
df_seoul_hospital.loc[~df_seoul_hospital["상호명"].str.contains("종합병원"), "상호명"].unique() 

#상호명에서 특정 단어가 들어가는 데이터만 가져온다. 
df_seoul_hospital[df_seoul_hospital["상호명"].str.contains("의료기")]

#꽃배달|의료기|장례식장|상담소|어린이집은 종합병원과 무관하기 때문에
#전처리를 위해 해당 텍스트를 한번에 검색한다.
#제거할 데이터의 인덱스만 drop_row에 담아주고 list 형태로 변환한다.
drop_row = df_seoul_hospital[
      df_seoul_hospital["상호명"].str.contains("꽃배달|의료기|장례식장|상담소|어린이집")].index
drop_row = drop_row.tolist()

#의원으로 끝나는 데이터도 종합병원으로 볼 수 없기 때문에 인덱스를 찾아서 drop_row2에 담고 list 형태로 변환
drop_row2 = df_seoul_hospital[df_seoul_hospital["상호명"].str.endswith("의원")].index
drop_row2 = drop_row2.tolist()

#삭제할 행을 drop_row에 합쳐준다.
drop_row = drop_row + drop_row2
len(drop_row)

#해당 셀을 삭제하고 삭제 전과 후의 행의 개수를 비교한다.
print(df_seoul_hospital.shape)
df_seoul_hospital = df_seoul_hospital.drop(drop_row, axis = 0)
print(df_seoul_hospital.shape)

#시군구명에 따라 종합병원의 숫자를 countplot으로 그린다.
df_seoul_hospital["시군구명"].value_counts().plot.bar()
plt.figure(figsize=(15, 4))
sns.countplot(data=df_seoul_hospital, x="시군구명", order=df_seoul_hospital["시군구명"].value_counts().index)

df_seoul_hospital["상호명"].unique()

 

9. 위경도 데이터 scatterplot 으로 표현하기

 

#서울에 있는 데이터의 위도, 경도 보기
#결과를 df_seoul 데이터프레임에 저장한다.
#새로운 변수에 데이터프레임을 저장할 경우 copy()를 사용한다.
df_seoul = df[df["시도명"] == "서울특별시"].copy()

#seaborn의 countplot을 사용해서 시군구명을 시각화한다.
df_seoul["시군구명"].value_counts().plot.bar(figsize=(10, 4), rot=30)

#시군구명을 seaborn의 countplot으로 그린다.
plt.figure(figsize=(15, 4))
sns.countplot(data=df_seoul, x="시군구명")

#Pandas의 plot.scatter를 통해 경도와 위도를 표시한다.
#grid : 격자 
df_seoul[["경도", "위도", "시군구명"]].plot.scatter(x="경도", y="위도", figsize(8, 7), grid=True)

#seaborn의 scatterplot을 통해 구별 경도와 위도를 표시한다.
plt.figure(figsize=(9, 8))
sns.scatterplot(data=df_seoul, x="경도", y="위도", hue="시군구명")

#seaborn의 scatterplot을 통해 상권업종중분류명 경도와 위도를 표시해본다.
plt.figure(figsize=(9, 8))
sns.scatterplot(data=df_seoul, x="경도", y="위도", hue="상권업종중분류명")

#seaborn의 scatterplot을 통해 전국 데이터(df)로 구별 경도와 위도를 표시한다.
plt.figure(figsize=(9, 8))
sns.scatterplot(data=df[:1000], x="경도", y="위도", hue="시도명")

 

10. folium 으로 위경도와 주소 데이터를 활용해 지도에 표현하기

 

아나콘다 프롬프트에서 folium을 설치한다.

conda install -c conda-forge folium

 

 

 

 

folium 사용예제

  • nbviewer.jupyter.org/github/python-visualization/folium/blob/master/examples/Quickstart.ipynb

 

#https://anaconda.org/conda-forge/folium에서 설치 
#conda 명령어로 설치
#지도 시각화를 위한 라이브러리
import folium
folium.Map()

#지도의 중심을 지정하기 위해 위도와 경도의 평균을 구한다.
df_seoul_hospital["위도"].mean()
df_seoul_hospital["경도"].mean()

df_seoul_hospital.tail(1)

map = folium.Map(location=[df_seoul_hospital["위도"].mean(), df_seoul_hospital["경도"].mean()], zoom_start=12)

for n in df_seoul_hospital.index:
   name = df_seoul_hospital.loc[n, "상호명"]
   address = df_seoul_hospital.loc[n, "도로명주소"]
   popup = f"{name}-{address}"
   location = [df_seoul_hospital.loc[n, "위도"], df_seoul_hospital.loc[n, "경도"]]
   folium.Marker(
      location=location,
      popup=popup,
   ).add_to(map)
map