촉촉한초코칩
[부스트코스] 데이터 사이언스 (3) 본문
공공데이터 상권정보 분석
필요한 라이브러리 불러오기 (pandas, numpy, seaborn)
import pandas as pd #엑셀
import numpy as np #수치 계산
import seaborn as sns #시각화
시각화를 위한 폰트 설정 (matplotlib.pyplot)
import matplotlib.pyplot as plt
#Window 한글 폰트 설정
plt.rc('font', family='Malgun Gothic')
#Mac 한글 폰트 설정
# plt.rc('font', family='AppleGothic')
# plt.rc('axes', unicode_minus=False) #한글 폰트 깨지는 것 방지
#그래프가 노트북 안에 보이게 하기 위해
%matplotlib inline
데이터 로드하기 (read_csv, shape)
- 판다스에서 데이터를 로드할 때는 read_csv를 사용한다.
- 데이터를 로드해서 df라는 변수에 담는다.
- shape를 통해 데이터 갯수를 찍는다.
- 결과는 (행, 열) 순서로 출력된다.
df = pd.read_csv("/data.csv")
df.shape
df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/hospitalList.csv", encoding="cp949")
df.shape
데이터 미리보기 (head, tail, sample)
df.head()
#tail > 마지막에 있는 데이터 불러오기
df.tail(1)
df.sample()
데이터 요약하기 (info, columns, dtypes)
#info
df.info()
#컬럼명만 출력
df.columns
#데이터 타입만 출력
df.dtypes
결측치 (isnull, plot)
- 데이터가 null값인지 아닌지
#false > 값이 있음
#true > 값이 없음 (null)
df.isnull()
#결측치가 몇개 있는지
null_count = df.isnull().sum()
null_count
#결측치를 plot.bar를 통해 막대그래프로 표현하기
null_count.plot()
null_count.plot.barh(figsize=(5,7))
#dataframe형태로 변환
df_null_count = null_count.reset_index()
df_null_count
* 내가 가져온 데이터는 결측치가 없음
칼럼명 변경하기 (columns)
df_null_count.columns = ["컬럼명", "결측치 수"]
df_null_count
정렬하기 (sort_values)
- 데이터프레임에 있는 결측치수 칼럼을 sort_values를 통해 정렬
- 데이터프레임에 있는 칼럼으로 by를 써야 한다.
#결측치가 많은 순으로 상위 10개만 출력하기
df_null_count_top = df_null_count.sort_values(by="결측치 수", ascending=False).head(10)
df_null_count_top
특정 컬럼만 불러오기 (tolist, head)
- NaN == Not a Number = 결측치
df["지점명"]
drop_columns = df_null_count_top["컬럼명"].tolist()
drop_columns
df[drop_columns].head()
제거하기 (drop)
#결측치 제거하기
print(df.shape)
df = df.drop(drop_columns, axis=1) #칼럼 기준 > 1, 행 기준 > 0
print(df.shape)
#제거한 후 확인
df.info()
기초 통계값 보기 (mean, median, max, min, count, describe, unique, nunique)
#평균값
df["위도"].mean()
#중앙값
df["위도"].median()
#최댓값
df["위도"].max()
#최소값
df["위도"].min()
#개수
df["위도"].count()
#기초통계값 요악하기 > describe
df["위도"].describe()
#2개의 컬럼 요약하기 > list 형태로 가져와야 한다.
df[["위도","경도"]].describe()
#문자열 데이터타입 요약보기
df.describe(include="object")
#freq : 빈도수
#중복 제거한 값 보기
#unique로 중복을 제거한 값을 보고 nuniue로 개수를 세어본다.
df["상권업종대분류명"].unique()
df["상권업종대분류명"].nunique()
df["상권업종중분류명"]
df["상권업종중분류명"].unique()
df["상권업종중분류명"].nunique()
df["상권업종소분류명"]
df["상권업종소분류명"].unique()
df["상권업종소분류명"].nunique()
#len
len(df["상권업종소분류명"].unique())
그룹화된 요약값 보기 (value_counts)
#그룹화된 요악값 보기 > value_counts (카테고리 형태의 데이터 갯수를 세어볼 수 있다.)
df["시도명"].head()
#시도명 세어보기
city = df["시도명"].value_counts()
city
#normalize=True 옵션을 사용해서 비율 구하기
city_normalize = df["시도명"].value_counts(normalize=True)
city_normalize
#Pandas는 plot 기능을 내장하고 있음
#시도명 수를 막대그래프로 표현하기
city.plot.line
city_normalize.plot.pie(figsize=(7,7))
city.plot.pie(figsize=(7,7))
city_normalize.plot.line
* 지역을 기준으로 하면 너무 많아서 그래프에 다 담기지 않음
기준을 세세하게 정해야 할 듯
* groupby 참고 : 04.3.6.2. GroupBy - 파이썬을 활용한 회계프로그래밍 (wikidocs.net)
city = df.groupby(["지역"]).value_counts()
city
seaborn 으로 빈도수 시각화 하기
#seaborn의 countplot으로 그려보기
sns.countplot(data=df, x="시도명")
sns.countplot(data=df, y="시도명")
#상권업종대분류명으로 갯수 세어보기
df["상권업종대분류명"].value_counts()
#normalize=True 사용해서 비율 구하기
df["상권업종중분류명"].value_counts(normalize=True)
#판다스의 plot.bar()을 사용해서 막대그래프 그려보기
c.plot.bar(rot=0) #rot = 0 : rotation(얼만큼 글자를 회전시킬 것인지)
#판다스의 plot.pie() 사용해서 파이그래프 그려보기
n.plot.pie()
#상권업종소분류명에 대한 그룹화된 값 카운트
c = df["상권업종소분류명"].value_counts()
#상권업종소분류명으로 갯수 세어보기
#판다스의 plot.bar() 사용해서 막대그래프 그려보기
c.plot.bar(figsize=(7,8), grid=True) #figsize : 글자크기, grid : 격자
* 지역을 기준으로 하면 너무 많아서 그래프에 다 담기지 않음
기준을 세세하게 정해야 할 듯
#seaborn의 countplot으로 그려보기
sns.countplot(data=df, x="지역")
sns.countplot(data=df, y="지역")
#상권업종대분류명으로 갯수 세어보기
df["병상수"].value_counts()
#normalize=True 사용해서 비율 구하기
df["진료과수"].value_counts(normalize=True)
#판다스의 plot.bar()을 사용해서 막대그래프 그려보기
c.plot.bar(rot=0) #rot = 0 : rotation(얼만큼 글자를 회전시킬 것인지)
#판다스의 plot.pie() 사용해서 파이그래프 그려보기
n.plot.pie()
#상권업종소분류명에 대한 그룹화된 값 카운트
c = df["연번"].value_counts()
#상권업종소분류명으로 갯수 세어보기
#판다스의 plot.bar() 사용해서 막대그래프 그려보기
c.plot.bar(figsize=(7,8), grid=True) #figsize : 글자크기, grid : 격자
원하는 데이터만 따로 추출해 오기 - 데이터 색인하기
#상권업종중분류명이 약국/한약방이 데이터만 가져와서
#df_medical 변수에 담기
df_medical = df[df["상권업종중분류명"] == "약국/한약방"].copy()
df_medical.head()
#상권업종대분류명에서 의료만 가져오기
#df.loc를 사용하면 행, 열을 함께 가져올 수 있다.
#가져온 결과를 value_counts를 사용해서 중분류의 개수를 세어본다.
df.loc[df["상권업종대분류명"] == "의료","상권업종중분류명"].value_counts()
m = df["상권업종대분류명"] == "의료"
df.loc[m, "상권업종중분류명"].value_counts()
#유사의료업만 따로 모아본다.
df[df["상권업종중분류명"] == "유사의료업"].shape
#상호명 그룹화해서 개수 세어보기
#value_counts 사용해서 상위 10개를 출력한다.
#하위 10개 > tail
df["상호명"].value_counts().head(10)
#df_medi 변수에서 상호명으로 갯수 세어보기
#가장 많은 상호 상위 10개 출력
df_medi["상호명"].value_counts().head(10)
여러 조건으로 색인하기
#상권업종소분류명이 약국인 것과
#시도명이 서울특별시인 데이터 가져오기
df_seoul_dr = df[(df["상권업종소분류명"] == "약국") & (df["시도명"] == "서울특별시")]
print(df_seoul_dr.shape)
df_seoul_dr
#위에서 색인한 데이터로 '시군구명'으로 그룹화해서 개수 세어보기
#구별로 약국이 몇 개 있는지 확인한다.
c = df_seoul_dr["시군구명"].value_counts()
c.head()
#normalize=True 통해서 비율 구해보기
n = df_seoul_dr["시군구명"].value_counts(normalize=True)
n.head()
#상권업종소분류명이 종합병원인것과
#시도명이 서울특별시인 데이터 가져오기
# df_seoul_hospital에 할당해서 재사용한다.
#copy하지 않고 할당하게 되면 df_seoul_hospital 값이 바뀌면 df의 데이터 값도 변경될 수 있다.
df_seoul_hospital = df[(df["상권업종소분류명"] == "종합병원") & (df["시도명"] == "서울특별시")].copy()
df_seoul_hospital
#시군구명으로 그룹화해서 구별로 종합병원의 수를 세어보기
df_seoul_hospital["시군구명"].value_counts()
텍스트 데이터 전처리하기
#텍스트 데이터 색인하기 전에 상호명 중 종합병원이 아닌 데이터 찾기
# ~ : 아닌 것 찾기
df_seoul_hospital[~df_seoul_hospital["상호명"].str.contains("종합병원")]
df_seoul_hospital.loc[~df_seoul_hospital["상호명"].str.contains("종합병원"),"상호명"].unique()
#상호명에서 특정 단어가 들어가는 데이터만 가져오기
df_seoul_hospital[df_seoul_hospital["상호명"].str.contains("꽃배달")]
#상호명에서 특정 단어가 들어가는 데이터만 가져오기 - 의료기
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_row
#의원으로 끝나는 데이터도 인덱스를 찾아서
#drop_row2에 담아주고 list 형태로 변환한다.
drop_row2 = df_seoul_hospital[df_seoul_hospital["상호명"].str.endswith("의원")].index
drop_row2 = drop_row2.tolist()
drop_row2
#삭제할 행을 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)
위경도 데이터 scatterplot 으로 표현하기
#Pandas의 plot.scatter를 통해 경도와 위도 표시하기
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=(16,12))
sns.scatterplot(data=df[:1000], x="경도", y="위도", hue="시도명")
folium 으로 위경도와 주소 데이터를 활용해 지도에 표현하기
Anaconda Prompt에서 conda install -c conda-forge folium 명령어를 실행해 folium을 설치한다.
#folium : 지도 시각화를 위한 라이브러리
import folium
#지도 중심을 지정하기 위해 위도와 경도의 평균을 구한다.
df_seoul_hospital["위도"].mean()
df_seoul_hospital["경도"].mean()
folium.Map(location=[df_seoul_hospital["위도"].mean(), df_seoul_hospital["경도"].mean()], zoom_start=12)
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
'Study > Big Data' 카테고리의 다른 글
파이썬으로 시작하는 데이터 사이언스 - 3강 (0) | 2023.10.21 |
---|---|
파이썬으로 시작하는 데이터 사이언스 - 2강 (0) | 2023.10.21 |
파이썬으로 시작하는 데이터 사이언스 - OT, 1강 (0) | 2023.10.13 |
[부스트코스] 데이터 사이언스 (5) (0) | 2023.04.12 |
[부스트코스] 데이터 사이언스 (4) (0) | 2023.04.01 |