728x90
오늘코드 - 서울시 코로나19 사이트 Pandas 단 한 줄로 크롤링 하기
영상을 실습한 코드 입니다.
https://www.youtube.com/watch?v=irHfF1ZcuY0
모든 날짜를 행에 만들어주기¶
확진자가 없는 날의 데이터도 만들어주기
In [55]:
# 첫 확진일부터 마지막 확진일까지 가져온다
# 데이터 프레임의 첫번째 날짜는 first_day, 마지막 날짜는 last_day에 담는다
# timeit: 코드의 소요시간을 여러 번 측정해 좀 더 정확히 파악할 때 사용
first_day = df.iloc[-1, 7]
In [56]:
last_day = df.iloc[0, 7]
In [59]:
# pd.date_range를 통해 시작하는 날짜부터 끝나는 날짜까지의 DatetimeIndex를 만들고
# days라는 변수에 저장
days = pd.date_range(first_day, last_day)
days[:5]
Out[59]:
In [62]:
df_days = pd.DataFrame({"확진일자":days})
df_days.head()
Out[62]:
In [64]:
daily_case = df["확진일자"].value_counts()
daily_case.head()
Out[64]:
In [66]:
df_daily_case = daily_case.to_frame()
df_daily_case
Out[66]:
In [68]:
df_daily_case.columns = ["확진수"]
df_daily_case.head()
Out[68]:
In [69]:
# 확진자가 없는 날도 일자에 표현이 되도록 전체 일자와 확진 데이터를 merge 로 합치기
all_day = df_days.merge(df_daily_case,
left_on = "확진일자",
right_on = df_daily_case.index, how = 'left')
all_day.head()
Out[69]:
누적 확진자 수 구하기¶
In [71]:
# 확진수를 fillna를 통해 결측치를 0으로 채워주고 누적해서 더해준다
all_day["누적확진"] = all_day["확진수"].fillna(0).cumsum()
all_day
Out[71]:
In [73]:
# 연도를 제외하고 월-일로 "일자"컬럼 만들기
all_day["일자"] = all_day["확진일자"].astype(str).map(lambda x : x[-5:])
all_day.head()
Out[73]:
In [76]:
# 확진수, 누적확진 컬럼을 갖는 데이터프레임을 만듭니다.
cum_day = all_day[["일자", "확진수", "누적확진"]]
cum_day = cum_day.set_index("일자")
cum_day.head()
Out[76]:
데이터프레임으로 그리기¶
In [81]:
# 데이터 프레임으로 확진수와 누적확진을 선그래프로 그리기
cum_day.plot(figsize=(15, 4))
Out[81]:
시리즈로 그리기¶
In [82]:
# 시리즈와 2개의 그래프 그리기
cum_day["확진수"].plot()
cum_day["누적확진"].plot(figsize=(15, 4))
Out[82]:
확진수만 따로 그리기¶
In [84]:
# 누적확진수와 확진수와 차이가 크면 제대로 보이지 않기 때문에 확진수만 그리기
cum_day["확진수"].plot(figsize = (15,4))
Out[84]:
누적확진만 따로 그리기¶
In [85]:
# 누적확진만 따로 그리기
cum_day["누적확진"].plot(figsize=(15,4))
Out[85]:
로그 스케일¶
In [87]:
# 차이가 너무 커서 그래프가 안보일땐 로그 스케일로 표현하면 차이가 큰 값의 스케일을 조정해줌
np.log(cum_day["누적확진"]).plot(figsize=(15, 4))
np.log(cum_day["확진수"]).plot()
Out[87]:
확진월과 요일 구하기¶
In [92]:
all_day["확진월"] = all_day['확진일자'].dt.month
all_day["확진요일"] = all_day["확진일자"].dt.dayofweek
all_day.head()
Out[92]:
요일별 확진 수¶
In [94]:
# 월별, 요일별 확진수를 groupby로 구하기
all_day_week = all_day.groupby(["확진월", "확진요일"])["확진수"].sum()
all_day_week = all_day_week.unstack().astype(int)
all_day_week
Out[94]:
In [96]:
# 숫자로 표현된 요일을 문자로 바꿔주기 위해 split으로 문자를 리스트로 변경한다
dayofweek = "월 화 수 목 금 토 일"
dayofweek = dayofweek.split()
dayofweek
Out[96]:
In [98]:
# 컬럼의 이름을 한글요일명으로 변경해준다
all_day_week.columns = dayofweek
all_day_week
Out[98]:
In [99]:
# style.background_gradient로 색상 표현
all_day_week.style.background_gradient(cmap = "Blues")
Out[99]:
거주지별 확진자¶
In [101]:
# 거주지(구별) 확진자의 빈도수를 구하고 시각화 한다
gu_count = df["거주지"].value_counts()
gu_count
Out[101]:
In [104]:
# 구별 확진자의 수를 시각화 한다
gu_count.sort_values().plot.barh(figsize = (10,12))
Out[104]:
In [106]:
# 서울에서 확진 판정을 받은 데이터 이기 때문에 거주지가 서울이 아닐 수 도 있음
# 거주지 별로 서울시에 해당되는 데이터만 따로 가져온다
gu = gu_count[:25].index
gu
Out[106]:
In [108]:
# 거주지가 서울이 아닌 지역을 따로 추출한다
set(gu_count.index) - set(gu)
Out[108]:
In [111]:
# 구를 전처리 하기 쉽게 컬럼으로 변환하기 위해 reset_index로 변환한다
df_gu = gu_count.reset_index()
df_gu.columns = ["구", "확진수"]
df_gu.head()
Out[111]:
In [115]:
# 서울의 확진자 와 타지역 비교 하기 위해 지역이라는 컬럼 만들고 아니라면 타지역
# 첫번째 방법
df.loc[df["거주지"].isin(gu), "지역"] = df["거주지"]
df["지역"] = df["지역"].fillna("타지역")
df["지역"].unique()
# 두번째 방법
df["지역"] = df["거주지"].map(lambda x : x if x in gu else "타지역")
df[["거주지", "지역"]].head()
Out[115]:
In [118]:
#지역 컬럼으로 확진자 빈도수를 구한다
gu_etc_count = df["지역"].value_counts()
gu_etc_count
Out[118]:
In [120]:
# 위에서 구한 빈도수로 막대그래프 그린다
gu_etc_count.sort_values().plot.barh(figsize=(8, 10))
Out[120]:
접촉력¶
In [122]:
# 접촉력 빈도수를 구한다
df["접촉력"].value_counts().head(20)
Out[122]:
In [124]:
# 접촉력의 unique 값만 구한다
df["접촉력"].unique()
Out[124]:
In [126]:
# 확인이 들어가는 접촉력만 찾는다
df.loc[df["접촉력"].str.contains("확인"), "접촉력"].unique()
Out[126]:
In [128]:
# 확인중, 확인 중 을 확인 중으로 변경
df.loc[df["접촉력"].str.contains("확인"), "접촉력"] = "확인 중"
In [130]:
#확인이 들어가는 접촉력만 찾기
df.loc[df["접촉력"].str.contains("확인"), "접촉력"].unique()
Out[130]:
In [133]:
# 접촉력 빈도수를 시각화
contact_count = df["접촉력"].value_counts()
contact_count_top = contact_count.sort_values().tail(30)
contact_count_top.plot.barh(figsize=(10, 12))
Out[133]:
In [135]:
#상위 15개만 구한다
top_contact = contact_count_top.tail(15)
top_contact
Out[135]:
In [137]:
# 접촉력 빈도수가 높은 목록에 대한 index값을 구해본다
top_contact.index
Out[137]:
In [140]:
# 위에서 구한 top_contact에 해당되는 데이터만 isin으로 가져온다
top_group = df[df["접촉력"].isin(top_contact.index)]
top_group.head()
Out[140]:
In [143]:
# 접촉력, 월별 빈도수를 groupby로 구한다
top_group.groupby(["접촉력", "월"])["연번"].count().unstack().fillna(0).astype(int)
Out[143]:
이태원 클럽 감염¶
In [144]:
df[df["접촉력"].str.contains("이태원")& (df["월"]== 6 )]
Out[144]:
감염경로 불명¶
In [149]:
# 접촉력이 확인중인 데이터만 구한다
df_unknown = df[df["접촉력"] == "확인 중"]
df_unknown.head()
Out[149]:
In [150]:
# 감염경로 불명이 어느정도인지 보기
unknown_weekly_case = df_unknown.groupby(["월", "주"])["연번"].count()
unknown_weekly_case.plot.bar(figsize=(15, 4))
Out[150]:
In [151]:
# 전체 확진수를 Values로 구하고 데이터 프레임 형태로 만들기
all_weekly_case = df["주"].value_counts().to_frame()
all_weekly_case.columns = ["전체확진수"]
all_weekly_case.head()
Out[151]:
In [153]:
# 전체 확진수를 Values로 구하고 데이터 프레임 형태로 만들기
unknown_weekly_case = df_unknown["주"].value_counts().to_frame()
unknown_weekly_case.columns = ["불명확진수"]
unknown_weekly_case.head()
Out[153]:
In [154]:
# all_weekly_case 와 unknown_weekly_case 를 비교
unknown_case = all_weekly_case.merge(unknown_weekly_case, left_index=True, right_index=True)
unknown_case = unknown_case.sort_index()
unknown_case.head()
Out[154]:
In [156]:
# 위에서 구한 결과를 시각화
unknown_case.plot(figsize = (15,4))
Out[156]:
In [157]:
# 감영 경로 "확인중"의 주별 비율
unknown_case["확인중비율"] = (unknown_case["불명확진수"] / unknown_case["전체확진수"]) * 100
unknown_case["확인중비율"].plot.bar(figsize = (15,4))
Out[157]:
'코딩' 카테고리의 다른 글
| DB (0) | 2020.08.19 |
|---|---|
| [데이터분석/오늘코드] 코로나19 데이터 pandas로 크롤링하기 2 (0) | 2020.08.09 |
| [데이터분석/오늘코드] 코로나19 데이터 pandas 로 크롤링하기 1 (0) | 2020.08.07 |
| [SW Expert Academy/파이썬 프로그래밍 기초(1)] 3. 기초 문법의 이해 강의 내용 정리 (0) | 2020.04.04 |