UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 0: invalid continuation byte
파일의 형식이 utf-8이 아니기 때문에 발생하는 오류이다.
인코딩 포맷을 찾는 모듈을 사용해서 해결해봤다.
✨chardet 모듈
pip install chardet
import chardet
with open("./datas/Summer-Olympic-medals-1976-to-2008.csv", "rb") as datas:
result = chardet.detect(datas.read(10000))
result
>>>
{'encoding': 'ISO-8859-1', 'confidence': 0.73, 'language': ''}
pd.read_csv("경로", encoding="ISO-8859-1")
sport = 종목
discipline = 하위 종목
# NaN 값이 들어 있는 행 찾기
df_target[df_target.isna().any(axis=1)]
# NaN 값이 들어 있는 행 삭제
df_target = df_target.dropna()
# Year: float ➡ int
df_target["Year"] = df_target["Year"].astype(int)
df_archery = df_target.copy(deep=True)
is_archery = df_archery["Sport"] == "Archery"
is_2008 = df_archery["Year"] == 2008
is_gold = df_archery["Medal"] == "Gold"
is_korea = df_archery["Country"] == "Korea, South"
df_archery = df_archery[is_archery & is_2008 & is_gold & is_korea]
df_kor = df_target.copy(deep=True)
# 대한민국 데이터
df_kor = df_kor[df_kor["Country"] == "Korea, South"]
# Athlete, Gender를 제외한 내용이 일치하는 데이터 제거
subset = ["City", "Year", "Sport", "Discipline", "Event", "Event_gender", "Medal"]
df_kor = df_kor.drop_duplicates(subset=subset)
# 피벗 테이블 적용
df_kor = df_kor.pivot_table(index=["Year", "Medal"], values="City", aggfunc="count")
# 정렬
sort_medal = {"Gold": 1, "Silver": 2, "Bronze": 3}
df_kor = df_kor.sort_index(
level=1, key=lambda x: x.map(sort_medal)
).sort_index(level=0, sort_remaining=False)
정렬 단계에서 시간이 오래 걸렸다.😂
sort_medal = {"Gold": 1, "Silver": 2, "Bronze": 3}
df_kor_2.sort_index(level=1, key=lambda x: sort_medal[x])
>>>
unhashable type: 'Index'
처음에는 x 값으로 뭐가 넘어오는지 정확히 몰라서 위와 같이 코드를 짰더니, 타입이 맞지 않다고 한다. 확인해보니 index 객체이다. 리스트랑 비슷하게 생겼다.
df_kor.index.get_level_values(1)
>>>
Index(['Bronze', 'Gold', 'Silver', 'Bronze', 'Gold', 'Silver', 'Bronze',
'Gold', 'Silver', 'Bronze', 'Gold', 'Silver', 'Bronze', 'Gold',
'Silver', 'Bronze', 'Gold', 'Silver', 'Bronze', 'Gold', 'Silver',
'Bronze', 'Gold', 'Silver'],
dtype='object', name='Medal')
공식 문서에서 Index 객체 내용도 참고하고, 구글링 하다가 map 함수 발견!
Index objects
pandas.Index.map
sort_medal = {"Gold": 1, "Silver": 2, "Bronze": 3}
df_kor.index.get_level_values(1).map(sort_medal)
>>>
Index([3, 1, 2, ... 3, 1, 2], dtype='int64', name='Medal')
그리고 힌트에서 sort_index()의 다른 인자를 확인해보라고 제안하는데,
sort_remaining=False 옵션 때문인 것 같다.
df_rank_10 = df_target.copy(deep=True)
# 1996년 데이터
df_rank_10 = df_rank_10[df_rank_10["Year"] == 1996]
# Athlete, Gender를 제외한 내용이 일치하는 데이터 제거
subset = ["City", "Year", "Sport", "Discipline", "Event",
"Country_Code", "Country", "Event_gender", "Medal"]
df_rank_10 = df_rank_10.drop_duplicates(subset=subset)
# 피벗 테이블 적용
df_rank_10 = df_rank_10.pivot_table(
index="Country", values="Medal", aggfunc="count"
).reset_index()
# 정렬
df_rank_10 = df_rank_10.sort_values(by="Medal", ascending=False)
# 상위 10개 표시
df_rank_10 = df_rank_10[:10]
df_rank_gold_10 = df_target.copy(deep=True)
# 1996년 데이터
df_rank_10 = df_rank_10[df_rank_10["Year"] == 1996]
# Athlete, Gender를 제외한 내용이 일치하는 데이터 제거
subset = ["City", "Year", "Sport", "Discipline", "Event",
"Country_Code", "Country", "Event_gender", "Medal"]
df_rank_10 = df_rank_10.drop_duplicates(subset=subset)
메달 종류별로 개수를 카운트하기 위해 Gold, Silver, Bronze 컬럼을 만든다.
# Gold, Silver, Bronze 컬럼 만들기
for idx, rows in df_rank_gold_10.iterrows():
medal = df_rank_gold_10.loc[idx, "Medal"]
if medal == "Gold":
df_rank_gold_10.loc[idx, "Gold"] = 1
elif medal == "Silver":
df_rank_gold_10.loc[idx, "Silver"] = 1
elif medal == "Bronze":
df_rank_gold_10.loc[idx, "Bronze"] = 1
집계 함수 count는 NaN 값을 무시하고 계산한다.
# 피벗 테이블 적용
df_rank_gold_10 = df_rank_gold_10.pivot_table(
index="Country", values=["Gold", "Silver", "Bronze"], aggfunc="count"
).reset_index().sort_values(by=["Gold", "Silver", "Bronze"], ascending=False)
# 상위 10개 표시
df_rank_gold_10 = df_rank_gold_10[:10]
# 컬럼 순서 변경
df_rank_gold_10 = df_rank_gold_10[["Country", "Gold", "Silver", "Bronze"]]