EDA - 테스트 3

slocat·2023년 12월 18일
0

start-data

목록 보기
43/75

1. 데이터 전처리

1-1. 데이터 불러오기

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 = 하위 종목

1-2. missing data 처리

# NaN 값이 들어 있는 행 찾기
df_target[df_target.isna().any(axis=1)]
# NaN 값이 들어 있는 행 삭제
df_target = df_target.dropna()

1-3. data type 정리

# Year: float ➡ int
df_target["Year"] = df_target["Year"].astype(int)

2-1. 2008년 대한민국 메달 리스트 찾기

  • 2008년 베이징 올림픽 양궁 종목의 금메달 리스트만 있는 데이터 프레임 만들기
  • 현재 데이터를 deep copy 하여 진행하기
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]

🔥 2-2. 대한민국 역대(1976-2008) 하계 올림픽 메달 획득 내역 확인

  • index: Year(내림차순) - Medal(Gold-Silver-Bronze)
  • 복식/단체 종목을 감안하여 Athlete, Gender를 제외한 내용이 일치하면 같은 경기에서 획득한 메달로 간주
  • ⭐내용이 일치하는 데이터를 삭제하는 방법 - drop_duplicate, groupby, pivot_table, ...
  • ⭐sort_index의 'key'에 딕셔너리 활용하기
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 옵션 때문인 것 같다.

2-3. 1996년 애틀란타 올림픽 총 메달 개수 상위 10개 국가 확인하기

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]

2-4. 1996년 애틀란타 올림픽 금메달 개수 기준 상위 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"]]

0개의 댓글