1단계 데이터 프레임 수정
df_target.drop(columns = ['자치구별(1)','사고유형별(2)'], inplace=True)
df_target.rename(columns={'자치구별(2)': '자치구', '사고유형별(1)': '사고유형', '구분별(1)': '구분'}, inplace=True)
# 다른방식 df_target.columns = ['자치구', '사고유형', '구분'] + list(df_target.columns[3:])
import re
df_target['구분'] = df_target['구분'].apply(lambda x: re.sub(r'\([^)]*\)', '', x).strip())
🙋♀️ 앞서 정규표현식을 써서 괄호를 삭제했던 게 기억나서 그 내용을 적용해 봄
그외
# 1-2
def del_bracket(value):
if '(' in value:
value = value.split(' ')[0]
value = value.strip()
return value
else:
return value
df_target.구분 = df_target.구분.apply(del_bracket)
이런 식으로도 품
#내 풀이
df_target.iloc[:, 3:] = df_target.iloc[:, 3:].replace('-', 0).fillna(0)
df_target.iloc[:, 3:] = df_target.iloc[:, 3:].astype('int')
#모범 답안
# 1-3
def change_na_type(value):
if value == '-' or type(value) == float:
return 0
elif type(value) == str and value.isdigit():
return int(value)
else:
return value
df_target = df_target.applymap(change_na_type)
✏️ 전반적으로 내 풀이가 더 짧아서 뿌듯했다. 다만 코드 효율성은 더 좋은가에 대해서는 확신하지 못함
#내 풀이
df_target['자치구'] = df_target['자치구'].replace('소계', '서울시')
#또 다른 방식 df_target.loc[df_target['자치구'] == '소계', '자치구'] = '서울시'
df_target.set_index(['자치구', '사고유형', '구분'], inplace=True)
#내풀이
df_past = df_target.loc[:, :'2004']
for idx in df_past.index.get_level_values(0).unique():
for col in df_past.columns:
total_a = 0
for idx2 in df_past.index.get_level_values(1).unique():
if idx2 != '합계':
try:
a = df_past.loc[(idx, idx2, '발생건수'), col].sum()
total_a += a
except KeyError:
pass
df_past.loc[(idx, '합계', '발생건수'), col] = total_a
print(idx, col, total_a)
df_target = pd.concat([df_past, df_target.loc[:,'2005':]], axis=1)
이런 식으로 값이 프린트 되는데 조금 복잡하게 풀었다.
다른 간단한 방식도 이번에 배웠다.
#다른 방식
for idx in df_past.index.get_level_values(0).unique():
accident_type = df_past.index.get_level_values('사고유형').unique()[1:]:
df_past.loc[(idx, '합계', '발생건수'), :] = df_past.loc[(idx, accident_type, '발생건수'), :].sum()
# 1-5 모범답안
df_target_year = df_target[df_target.columns[:17]]
idx_level_1_list = df_target_year.loc['서울시'].index.get_level_values(0).unique()
idx_total = sum(df_target_year.loc[('서울시', idx1, '발생건수')] for idx1 in idx_level_1_list if idx1 != '합계')
df_target.loc[('서울시', '합계', '발생건수'), df_target.columns[:17]] = idx_total
2단계 가공 및 추출
df_result = df_target[df_target.index.get_level_values(2)=='발생건수']
df_result = df_result.droplevel(level=2)
#내 풀이
df_result = df_target.loc[(slice(None), slice(None), '사망자수'), :]
#구분 제거
df_result = df_result.droplevel(2)
#자치구와 사고유형 위치 변경
df_result = df_result.swaplevel(0, 1, axis=0)
#사고유형 인덱스는 type_list와 동일하게 정렬
df_result= df_result.loc[pd.IndexSlice[type_list, :], :]
#조건엔 없고 사진에 있는
df_result = df_result.loc[:,'2005':]
#모범답안
2-2
# 방법1: sort_index 사용
type_order = {idx1: i for i, idx1 in enumerate(type_list)}
df_result = df_target.loc[df_target.index.get_level_values(2)=='사망자수', df_target.columns[17:]]
df_result = df_result.droplevel(level=2)
df_result = df_result.swaplevel(0, 1)
df_result = df_result.sort_index(key=lambda x: x.map(type_order))
check_02_02(df_result)
display(df_result)
# 방법2: 직접 index 순서 지정
df_result = df_target.loc[df_target.index.get_level_values(2)=='사망자수', df_target.columns[17:]]
df_result = df_result.droplevel(level=2)
df_result = df_result.swaplevel(0, 1)
idx_tuple_list = [(idx1, idx2) for idx1 in type_list for idx2 in gu_list if (idx1, idx2) in df_result.index]
df_result = df_result.loc[[tp for tp in idx_tuple_list if tp in df_result.index]
3단계 원하는 정보 얻기
df_target3 = df_target.copy()
df_target3 = df_target3.loc[:, '2005':]
df_target3 = df_target3.loc[(slice(None), slice(None), ['발생건수', '사망자수']), :].sort_index()
df_target3 = df_target3.loc[df_target3.index.get_level_values(1) != '건널목', :]
result_list = []
for idx in df_target3.index.get_level_values(0).unique():
for col in df_target3.columns:
for idx2 in df_target3.index.get_level_values(1).unique():
try:
num = df_target3.loc[(idx, idx2, '사망자수'), col]
den = df_target3.loc[(idx, idx2, '발생건수'), col]
if (num != 0) or (dem !=0):
rate = round(num / den * 100, 2)
except:
rate = 0
result_list.append([idx, idx2, col, rate])
result_df = pd.DataFrame(result_list, columns=['자치구', '사고유형', '년도', '비율'])
df_result = pd.pivot_table(result_df, index = ['자치구', '사고유형'], columns=['년도'], values='비율').rename_axis(columns=None)
df_result = df_result.loc[pd.IndexSlice[gu_list, type_list, :], :]
#모범답안
df_result = df_target.loc[df_target.index.get_level_values(2).isin(['발생건수', '사망자수']), df_target.columns[17:]]
for gu in gu_list:
for type_ in type_list:
idx_dead = (gu, type_, '사망자수')
idx_total = (gu, type_, '발생건수')
if idx_dead in df_result.index and idx_total in df_result.index:
df_result.loc[(gu, type_, '사망률')] = (df_result.loc[(gu, type_, '사망자수')] / df_result.loc[(gu, type_, '발생건수')] * 100).apply(lambda x: round(x, 2))
df_result = df_result.loc[df_result.index.get_level_values(2) == '사망률']
df_result = df_result.droplevel(level=2)