지금까지 설명한 pandas 의 개념을 활용하여 NC 다이노스 선수 데이터를 활용하여 분석해보겠다. 사실 분석이라 하기엔 그렇고 간단히 살펴보겠다.
NC 다이노스 데이터는 3개의 시트가 저장되어 있어서 시트 모두를 불러와야한다. 그리고 엑셀 파일이다.
따라서 코드는
data = pd.read_excel('NC Dinos.xlsx',sheet=None)
nc13,nc14,nc15 = data.values()
위와 같은 코드를 사용하여 각각의 변수에 데이터 값을 불러온다.
위와 같이 연도 구분이 없으므로 연도를 컬럼을 추가한다.
그리고 13년,14년,15년 데이터를 모두 하나의 데이터프레임으로 만들어준다.
for i,j in zip([2013,2014,2015],[nc13,nc14,nc15]):
j['연도'] = i
df = nc13.merge([nc14,nc15],ignore_index=True)
# df = pd.concat([nc13,nc14,nc15],ignore_index=True) <- merge와 똑같은 결과
df.shape
#out
(60,20)
사실 for 문과 zip을 사용하지 않고 바로 컬럼 삽입을 해주면 되지만 추 후에 model fit이나 predict할 때 사용하기 편하므로 위와 같이 조금은 어려운 코드를 짰다. 이 글을 읽는 사람들이 위 코드를 많이 활용을 했으면 좋겠다.
1. 2015년 타율이 가장 높은 선수 상위 10명의 이름을 뽑아내라
단, 타율이 같을 경우 안타 개수가 많은 순으로 정렬
t1 = df[df['연도'] == 2015].sort_values(by=['타율','안타'],ascending=False).head(10)
t1
이름만 뽑아내야 하니
t1['선수명'].tolist()
#out
'''
['테임즈', '박정준', '조평호', '나성범', '박민우', '김종호', '이호준', '모창민', '용덕한', '조영훈']
'''
한 번 더 나아가서 상위 10명의 선수와 타율을 데이터 프레임형식으로 정리해보겠다.
t1[['선수명','타율','안타']]
한결 보기가 편해졌다.
박정준 선수와 테임즈 선수의 안타 개수가 상당히 차이 나는 것을 보고 단순히 타율만으로 결정해서는 안되겠구나 라는 것을 깨닫게 된다.
2. 2013~2015년 선수별 3년 평균 안타 수
- 평균 안타수가 높은 순서로 정렬해서 보이기
df.pivot_table(index='선수명',values='안타',aggfunc='mean').sort_values('안타',ascending=False).head(10)
pivot_table을 사용해 인덱스를 선수명으로 하고 values를 안타로 정하여 aggfunc='mean'을 함으로써 평균 안타수를 나타내주는 pivot_table을 만들 수 있다. 이 때 aggfunc='mean'은 default 값이니 사실 따로 설정을 안해줘도 되지만 정확히 하기 위해 해주는 것이 좋다.
만약 pivot_table을 사용하지 않고는 어떻게 할까?
tmp = df.set_index(['선수명','안타'])
인덱스를 선수명과 안타로 설정한 데이터 프레임을 하나 만들어준다.
tmp['안타'].unstack(0).mean(axis=1).sort_values(ascending=False).head(10)
unstack(0)로 연도별(컬럼), 선수별(로우) 안타수를 보기 위한 구조로 변경한 후 컬럼의 평균을 구한 다음 정렬을 시킨 것이다.
pivot_table이 훨~~씬 편하다는 것을 느낀다.
3. 평균 안타수 기준 상위 10위 타자들의 3년간 안타, 홈런, 타율 조회
참고) NaN 값이 있을 경우 '-'로 대체해서 표현 => df.fillna('-')
우선 전체 데이터 값에서 필요한 컬럼만 뽑아서 변수에 저장하겠다.
df2=df[['선수명','연도','안타','홈런','타율']].copy()
그리고 위에서 구했던 안타수 기준 상위 10위 타자들의 이름을 리스트 형식으로 추출하겠다.
위에 코드를 그대로 복붙한 후 만들어 주면 된다.
name=df.pivot_table(index='선수명',values='안타',aggfunc='mean').sort_values('안타',ascending=False).head(10).index.tolist()
name
#out
'''
['테임즈', '나성범', '김종호', '이호준', '이종욱', '김태군', '손시헌', '박민우', '모창민', '지석훈']
'''
그 다음 선수명을 인덱스로 변경한다.
tmp = df2.set_index('선수명').loc[name]
그리고 구조를 재배열한다.
tmp.reset_index().set_index(['연도','선수명']).unstack(0)
원하는대로 깔끔하게 나왔다! 하지만 이 과정은 약간의 귀찮음이 있다. 따라서 한줄 코드로 변환시켜봤다.
df.set_index(['연도','선수명'])[['안타','홈런','타율']].unstack(0).loc[name]
기존의 원 데이터 프레임에서 구조를 먼저 잡고 추출하는 방법이다.
위와 같은 코드 끝에 .fillna('-')을 붙여주면
원하는 결과가 추출이 된다.
4. 연도별 팀의 총 안타수, 총 홈런수, 총 도루수
이 역시 예상했듯이 바로 pivot_table을 사용하면 된다.
t=df1.pivot_table(index='연도',values=['안타','홈런','도루'],aggfunc='sum')
t
values(numeric type 이어야 됨)에 원하는 컬럼을 넣어서 pivot_table을 생성시키면 완성이다.
'Python > python 기초' 카테고리의 다른 글
Pandas를 활용한 영화 평점 분석 (0) | 2020.08.25 |
---|---|
파이썬 리뷰 (2) | 2020.07.03 |
Pandas - 3 (0) | 2020.02.23 |
Pandas - 2 (0) | 2020.02.02 |
Pandas - 1 (0) | 2020.01.31 |
댓글