본문 바로가기

코딩

[데이터분석/오늘코드] 코로나19 데이터 pandas로 크롤링하기 2

728x90

오늘코드 - 서울시 코로나19 사이트 Pandas 단 한 줄로 크롤링 하기

영상을 실습한 코드 입니다.

https://www.youtube.com/watch?v=irHfF1ZcuY0

 

covid19_today_cp

확진일

In [118]:
# 날짜별 확진일 빈도 내림차순
df["확진일"].value_counts()
Out[118]:
3.10.    46
6.12.    30
6.06.    29
6.05.    27
3.9.     26
         ..
3.5.      1
5.31.     1
2.6.      1
4.30.     1
5.17.     1
Name: 확진일, Length: 169, dtype: int64
In [119]:
df["확진일"].head(1)
Out[119]:
0    8.7.
Name: 확진일, dtype: object
In [120]:
# 데이터 타입을 변경해서 날짜로 변환
# 연도 추가하고 , 을 -로 대체

df["확진일자"] = pd.to_datetime("2020-"+df["확진일"].str.replace(".","-"))
df[["확진일","확진일자"]].head()
Out[120]:
확진일 확진일자
0 8.7. 2020-08-07
1 8.7. 2020-08-07
2 8.7. 2020-08-07
3 8.7. 2020-08-07
4 8.7. 2020-08-07
In [121]:
# 월만 추출
df["월"] = df["확진일자"].dt.month
df[["확진일","확진일자", "월"]].tail()
Out[121]:
확진일 확진일자 월
1657 1.31. 2020-01-31 1
1658 1.30. 2020-01-30 1
1659 1.30. 2020-01-30 1
1660 1.30. 2020-01-30 1
1661 1.24. 2020-01-24 1
In [122]:
# 해당연도의 몇번째 주인지 추출
df["주"] =  df["확진일자"].dt.week
df[["확진일","확진일자", "월", "주"]].head()
Out[122]:
확진일 확진일자 월 주
0 8.7. 2020-08-07 8 32
1 8.7. 2020-08-07 8 32
2 8.7. 2020-08-07 8 32
3 8.7. 2020-08-07 8 32
4 8.7. 2020-08-07 8 32

선그래프 그리기

In [123]:
# 확진일자로 선그래프 그리기
df["확진일자"].value_counts().sort_index().plot(figsize=(15, 4))
plt.axhline(30, color="red", linestyle=":")
Out[123]:
<matplotlib.lines.Line2D at 0xbf1da10>

선그래프에 값 표시하기

In [124]:
# value_counts()
# 시리즈의 값이 정수, 문자열, 카테고리 값인 경우에 각각의 값이 나온 횟수를 셀 수 있음
# sort_index()
# 인덱스를 기준으로 값을 정렬
# iloc : 순서를 나타내는 정수 기반의 2차원 인덱싱
# loc : 라벨값 기반의 2차원 인덱싱

# 일자별 확진자수를 선그래프로 그림
# 연도는 모두 2020년이기 때문에 월일만 표기되도록 슬라이싱을 사용해 "월일"컬럼을 만든다
df["월일"] = df["확진일자"].astype(str).map(lambda x : x[-5:])
day_count = df["월일"].value_counts().sort_index()
day_count.iloc[2]
Out[124]:
3
In [125]:
day_count.head(40)
Out[125]:
01-24     1
01-30     3
01-31     3
02-02     1
02-05     2
02-06     1
02-07     1
02-16     2
02-19     2
02-20     5
02-21     2
02-22     4
02-23     4
02-24     4
02-25    16
02-26    10
02-27    13
02-28     8
02-29     5
03-01     6
03-02     6
03-03     1
03-04     5
03-05     1
03-06     7
03-07     7
03-08    10
03-09    26
03-10    46
03-11    17
03-12    12
03-13     9
03-14     8
03-15     6
03-16    13
03-17     4
03-18    11
03-19    17
03-20    17
03-21     8
Name: 월일, dtype: int64
In [126]:
for i in range(len(day_count)):
        case_count = day_count.iloc[i]
        if case_count>20:
            print(i, case_count)
27 26
28 46
46 22
47 22
49 24
95 25
104 27
105 29
110 25
111 30
116 24
149 21
152 21
In [127]:
g = day_count.plot(figsize = (15,4))
for i in range(len(day_count)):
    case_count = day_count.iloc[i]
    if case_count>20:
        g.text(x=i,y=case_count, s=case_count)

확진자가 가장 많이 나온 날

In [128]:
day_count
Out[128]:
01-24     1
01-30     3
01-31     3
02-02     1
02-05     2
         ..
08-03     9
08-04     6
08-05     9
08-06     9
08-07    17
Name: 월일, Length: 168, dtype: int64
In [129]:
# describe를 통해 일자별 확진자 수를 describe를 통해 요약
day_count.describe()
Out[129]:
count    168.000000
mean       9.892857
std        7.312556
min        1.000000
25%        4.000000
50%        8.000000
75%       14.000000
max       46.000000
Name: 월일, dtype: float64
In [130]:
# 확진자가 가장 많았던 날
day_count[day_count == day_count.max()]
Out[130]:
03-10    46
Name: 월일, dtype: int64
In [131]:
# 확진자가 가장 많았던 날의 발생이력
df[df["월일"] == "03-10"].head()
Out[131]:
연번 환자 확진일 거주지 여행력 접촉력 조치사항 확진일자 월 주 월일
1460 202 7567 3.10. 노원구 - 콜센터직원 접촉 서울의료원(퇴원) 2020-03-10 3 11 03-10
1461 201 7711 3.10. 노원구 - 콜센터직원 접촉 서울의료원(퇴원) 2020-03-10 3 11 03-10
1462 200 7555 3.10. 구로구 - 구로구 콜센터 관련 서남병원(퇴원) 2020-03-10 3 11 03-10
1463 199 7725 3.10. 양천구 - 구로구 콜센터 관련 서남병원(퇴원) 2020-03-10 3 11 03-10
1464 198 7539 3.10. 양천구 - 콜센터직원 접촉 서남병원(퇴원) 2020-03-10 3 11 03-10

막대그래프 그리기

In [132]:
# 선 그래프를 막대그래프로 표현
day_count.plot.bar(figsize = (30,4))
Out[132]:
<matplotlib.axes._subplots.AxesSubplot at 0x90fd290>

최근 데이터만 슬라이싱으로 나눠 그리기

In [133]:
# 슬라이싱을 통해 최근 데이터만 그립니다.

# 데이터 프레임 정의
g = day_count[-50:].plot.bar(figsize=(15, 4))
# 슬라이싱
g.axhline(day_count.median(), linestyle=":", color="red")

# 텍스트 입력
for i in range(50):
    case_count = day_count[-50:].iloc[i]
    if case_count > 10:
        g.text(x=i-0.5, y=case_count, s=case_count)

월별 확진자 수 그리기

In [134]:
# 월별 확진자 수에 대한 빈도수를 구해서 시각화
month_case = df["월"].value_counts().sort_index()
g = month_case.plot.bar(rot=0)

for i in range(len(month_case)):
    g.text(x=i-0.2, y=month_case.iloc[i]+10, s=month_case.iloc[i])

주단위 확진자수 그리기

In [135]:
# 주별로 빈도수

weekly_case = df["주"].value_counts().sort_index()
weekly_case.plot(figsize=(15, 4))
Out[135]:
<matplotlib.axes._subplots.AxesSubplot at 0xd02a6f0>
In [136]:
# 주 단위 빈도수 막대그래프로 그리기
weekly_case.plot.bar(figsize=(15, 4), rot=0)
Out[136]:
<matplotlib.axes._subplots.AxesSubplot at 0xd02a710>

월-주 함께 그리기

In [137]:
# 월, 주로 그룹화 하여 빈도수를 계산
month_weekly_case = df.groupby(["월","주"])["연번"].count()
month_weekly_case
Out[137]:
월  주 
1  4       1
   5       6
2  5       1
   6       4
   7       2
   8      17
   9      56
3  9       6
   10     37
   11    124
   12     76
   13    105
   14     43
4  14     85
   15     47
   16     15
   17      4
   18      5
5  18      3
   19     51
   20     48
   21     39
   22     87
6  23    134
   24    125
   25    106
   26     78
   27     17
7  27     50
   28     57
   29     48
   30     97
   31     29
8  31      9
   32     50
Name: 연번, dtype: int64
In [138]:
month_weekly_case.plot.bar(figsize=(15,4), rot=30)
Out[138]:
<matplotlib.axes._subplots.AxesSubplot at 0xd07d3d0>