Day 18(Day 16 이어서)
컬럼명 변경하기
# 방법1) 리스트 컴프리헨션 사용
weekday_list = [ day for day in "월화수목금토일"]
weekday_list = weekday_count.index
# list("월화수목금토일") 도 가능
# weekday_count의 인덱스가 weekday_list와 동일하다
# 방법2) 람다식 사용
weekday_count.index.map(lambda x : "월화수목금토일"[x])
# weekday_count.index와 인덱스 결과(0~6 : 월~일)의 각 요소를 맵핑한다
시각화 관련
시카레오님 블로그 참고 https://sikaleo.tistory.com/14
1. 그래프에 수평선/수직선 그리기
# 수평선 그리기
plt.axhline(1500, c='k', lw=0.5, ls=":")
# c='k' 라인 색깔(b 파랑/r 빨강/k 검정/y 노랑 등)
# lw=0.5 라인 두께
# ls="-" 라인 유형(점선(:), 찍찍(-) 등)
# 수직선 그리기
plt.axvline(1500, c='k', lw=0.5, ls=":")
2. xlabel(x축 라벨) 회전 각도 지정
day_count[:30].plot.bar(figsize=(10,2),rot=80)
# rot x축 라벨을 80도로 기울여라 (rot=0일 때 가로로 평범하게 나온다)
3. 범례 위치 지정
plt.legend(bbox_to_anchor=(1, 1))
전체 기간 데이터 만들기
1) 데이터의 일부를 확인한다
df.head()
df.tail()
2) 데이터의 첫 날과 마지막 날을 찾는다
last_day = df.iloc[0]['확진일']
first_day = df.iloc[-1]['확진일']
3) date_range()로 전체 기간 데이터를 만든다
all_day = pd.date_range(start=first_day, end=last_day)
# pd.date_range() 시작일과 종료일을 지정하면 양 일을 포함한 기간 전체를 생성해준다
# 년-월-일, 년/월/일, 월/일/년 등과 같은 다양한 날짜 형식 지원
# datetime모듈의 datetime자료형도 지원한다
결측치 채우기
df.fillna(0) #결측값을 0으로 채우기
df.fillna('없음') #결측값을 '없음'이라는 문자열로 채우기
df.fillna(method = 'ffill') #결측값을 선행하는 값으로 채우기 # method='pad'도 가능
df.fillna(method = 'bfill') #결측값을 후행하는 값으로 채우기 # method = 'backfill'도 가능
df.fillna(df.mean()) #결측값을 df의 평균으로 채우기
누적합
df_all_day['확진수'] = df_all_day['확진수'].cumsum()
# cumsum() numpy의 누적합 함수
# axis = 0 같은 컬럼값끼리 누적합 (주의!!)
# axis = 1 같은 행값끼리 누적합 (주의!!)
데이터 프레임 공백 제거하기
df['거주구'].str.strip() # 문자열 양옆 공백제거
df['거주구'].str.rstrip() # 문자열 오른쪽 공백제거
df['거주구'].str.lstrip() # 문자열 왼쪽 공백제거
▷ .str. 은 Series accessor기 때문에 Series에서만 사용된다. 문자열 중 일부만 일치해도 적용된다.
값 변경하기
df.replace({'컬럼명':'변경 이전 값'}, '변경 이후 값')
ex) df.replace({'거주구':'타시도'}, '기타')
replace()와 .str.replace()
replace() : df/Series 모두 사용 가능, 문자열이 완전히 일치해야 적용(정규표현식 사용하면 일부만 일치해도 적용됨)
.str.replace() : Series에서만 사용 가능, 문자열 일부만 일치해도 적용
pd.crosstab()
pd.crosstab(index = df.연도, columns = df.퇴원현황)
# index = 행, columns = 열
pd.crosstab(index = df.연도, columns = df.퇴원현황, normalize=True)
# normalize=True == normalize='all' 값 전체를 1로 보고 각 결과의 비율 계산
leave_hospi = pd.crosstab(index = df.거주구, columns = df.연도월)
leave_hospi.T.plot(kind='bar')
# crosstab코드를 변수에 저장하고 .T로 전치행렬을 하여 그려줄 수도 있다
leave_hospi.style.background_gradient(cmap='summer_r')
# background_gradient() 크로스탭 결과에 배경색을 입혀 색상의 진하기로 빈도수가 표현된다
pivot_table()
pd.pivot_table(data=df, index='거주구', columns = '해외유입', values='환자', aggfunc='count')
pd.pivot_table(data=df, index='거주구', columns = '해외유입', aggfunc='count')['환자']
# data 활용할 데이터 지정
# index 행 지정
# columns 열 지정
# values 값 지정
# aggfunc 값 집계 방법 지정(count=len, mean 등)
*크로스탭과 피벗테이블
크로스탭이 피벗테이블보다 효율적이다(더 쉽게 구현할 수 있다)
불리언 인덱싱(Boolean Indexing)
1) 형태
.loc[행]
.loc[행, 열]
.loc[조건, 열] #조건을 쓸 때는 loc를 쓰지 않고 df[조건식]으로만 감싸도 가능
2) 예시코드
df.loc[ (df.거주구 == '강남구') & (df.요일명 == '일')]
# 강남구에 살면서 일요일에 확진된 데이터를 추출하라
df.loc[ (df.거주구 == '강남구') & (df.여행력 == '일본'), ["확진일",'접촉력']]
# 강남구에 살면서 일본 여행력이 있는 데이터의 확진일, 접촉력 컬럼만 가져와라
.str.contains()
df['접촉력_대문자'].str.contains('PC')
# .str.contains 'PC'를 포함하는 데이터를 찾아라
df['접촉력'].str.contains('pc|PC|Pc').value_counts()
# | 연산자를 사용하여 3가지 경우를 찾으라고 지시
isin()
df.loc[df['거주구'].isin(['강남구','서초구','송파구']),'접촉력']
# isin() 리스트[] 안의 값 중 하나를 포함한 행을 찾는다
groupby()
1) 기본
df.groupby(by='거주구')['환자'].count()
# by 그룹화 기준 컬럼
# 거주구를 기준으로 그룹화하여 환자 컬럼의 빈도수를 구하라
df.groupby(by=['거주구', '여행력'])['환자'].count()
# 그룹화 기준 컬럼으로 여러 개를 사용할 때는 리스트[ ]로 감싸준다
2) unstack()
df.groupby(by=['거주구', '해외유입'])['환자'].count().unstack()
# unstack() 맨 마지막 인덱스값[-1](여기서는 해외유입)을 끌올하여 컬럼으로 만든다
df.groupby(by=['거주구', '해외유입'])['환자'].count().unstack(level=0)
# unstack(level=0) 0번째 인덱스(여기서는 거주구)를 끌올하여 컬럼으로 만든다
<0304>
<전처리 전 수도코드 만들기>
1. 2013~2015년 데이터
2015~데이터와 같은 형태로 연도와 월을 컬럼으로 만들어준다
2. 2015~ 데이터
제곱미터당 평균 분양가격 à 3.3제곱미터당 가격으로 변경한다.
전용면적을 전체만 사용한다
3. 1, 2데이터를 concat으로 병합해서 하나로 만들어 2013~ 최근까지의 분양가를 분석한다.
파일 경로로 가져오기
file_paths = sorted(glob("./apt*.csv"))
# sorted() 파일 목록이 여러 개일 때 오름차순으로 정렬해준다
# ./ 나는 경로 설정 이렇게 해야
pd.read_csv(file_paths[1], encoding='cp949')
# 파일 경로로 찾아 지정해준 file_paths라는 변수는 list형태라 슬라이싱 가능
# encoding='cp949' csv파일 읽어올 때 한글 인코딩
# 파일 로드 시 OSError 발생하면 engine="python" 추가
# 또는 r(" ") 형태의 r-string 사용. 경로를 문자 그대로 읽으라는 의미
데이터 타입 변경
1) 결측치가 섞여있을 때는 astype()으로 제대로 변환되 않는다.
2) pd.to_numeric으로 변환하고 error를 어떻게 처리할 것인지 지정하여 데이터타입을 변경한다.
pd.to_numeric(df_last['분양가격'], errors='coerce')
# pd.to_numeric() 문자 타입을 수치 데이터 형태로 변경하는 판다스 내장함수
# astype() 은 결측치가 섞여있을 때 제대로 변환되지 않는다
# errors='raise' 에러를 그대로 발생시킨다
# errors='coerce' 바꿀 수 없는 값이 있으면 강제로 NaN으로 변경시킨다
# errors='ignore' 바꿀 수 없는 값은 무시하고 지나가며 데이터타입은 그대로다
컬럼값 수정하기
df_last['규모구분'].str.replace('전용면적|제곱미터이하','',regex=True)
# | or연산자 판다스 기호
# .str.replace("a","b") 모든 문자 a를 b로 변경
# regex=True 정규표현식 사용여부. 미래 버전에는 regex=False가 기본 값이 될 것이니 이걸 쓰는 습관을 들여라
불필요한 컬럼 제거
# 방법1 drop(columns=' ')로 삭제할 열 직접 자정
df.drop(columns=['규모구분','분양가격'])
# drop() 데이터프레임에서 열을 삭제하는 메서드로 pop과 달리 원본이 변경되지 않는다
# 방법2
df.drop(labels=['규모구분','분양가격'], axis=1)
# labels 행과 열 모두 지정할 수 있기 때문에
# axis=0/1을 꼭 지정해줘야 한다
기타
▷치사율을 구할 때는 normalize=True를 쓰지 않는다
normalize=True는 전체를 1로 보고 크로스탭의 각 결과의 비율을 구하기 때문에 치사율 집계에 적합하지 않다. (사망자 수 / 전체 환자 수)로 계산해줘야 한다.
▷df.요일
컬럼명에 띄어쓰기나 특수문자가 들어갔을 때 오류가 날 수 있다.
▷df[조건식]과 df.loc[조건식]의 차이
df[조건식]은 컬럼을 바로 인덱싱
loc는 row와 column을 이용해 인덱싱
▷.str.count는 내부 api구현에 따라 float 자료형으로 나온다.
▷fancy indexing
it means passing an array of indices to access multiple array elements at once. 「 Python Data Science Handbook 」
요소에 개별로 접근하여 인덱싱하지 않고 한번에 가져오는 것 ex) df.iloc[:, [1, 2, 5]]
▷df.plot.bar(stacked=True, legend='reverse')
stacked=True 하나의 변수 막대 위에 다른변수 막대를 쌓아 올려서 시각화한다
legend='reverse' 범례 순서를 역순으로
출처) 멋쟁이 사자처럼 AI School 7기 박조은 강사님 수업자료