pandas 100제: 판다스 연습문제와 풀이 · 9장

081–090 합치기와 모양 바꾸기

merge inner·left·outer, left_on·right_on, indicator, concat, melt, pivot, crosstab, explode 연습문제

4분 읽기

여러 표를 합치고, 넓은 표와 긴 표를 오가는 문제입니다.

준비 코드

이 장의 문제는 아래 코드를 먼저 실행한 상태에서 풉니다.

Pythonimport pandas as pd

students = pd.DataFrame({'name': ['김민준', '이서연', '박지호', '최수아'],
                         'class': ['A', 'B', 'A', 'C']})
clubs = pd.DataFrame({'name': ['김민준', '박지호', '정민서'],
                      'club': ['축구', '밴드', '독서']})
scores = pd.DataFrame({'student': ['김민준', '이서연', '박지호', '최수아'],
                       'kor': [85, 92, 58, 77], 'eng': [78, 88, 64, 95]})

081. 공통 열로 합치기

students와 clubs를 name으로 합치세요(양쪽에 있는 학생만).

정답 보기
Pythonstudents.merge(clubs, on='name')
결과     name class  club
0  김민준     A  축구
1  박지호     A  밴드

082. 왼쪽 기준 합치기

모든 학생을 남기고 동아리 정보를 붙이세요.

정답 보기
Pythonstudents.merge(clubs, on='name', how='left')
결과     name class  club
0  김민준     A  축구
1  이서연     B   NaN
2  박지호     A  밴드
3  최수아     C   NaN

짝이 없는 동아리는 NaN이 됩니다.

083. 열 이름이 다를 때

students의 name과 scores의 student를 기준으로 합치세요.

정답 보기
Pythonstudents.merge(scores, left_on='name', right_on='student').drop(columns='student')
결과     name class  kor  eng
0  김민준     A   85   78
1  이서연     B   92   88
2  박지호     A   58   64
3  최수아     C   77   95

084. 어느 쪽에 있었는지

양쪽 모든 행을 남기고, 행이 어디서 왔는지 표시하세요.

정답 보기
Pythonstudents.merge(clubs, on='name', how='outer', indicator=True)
결과     name class  club      _merge
0  김민준     A  축구        both
1  박지호     A  밴드        both
2  이서연     B   NaN   left_only
3  정민서   NaN  독서  right_only
4  최수아     C   NaN   left_only

085. 아래로 이어 붙이기

students 아래에 새 학생 정민서(B반)를 붙이세요.

정답 보기
Pythonnew = pd.DataFrame({'name': ['정민서'], 'class': ['B']})
pd.concat([students, new], ignore_index=True)
결과     name class
0  김민준     A
1  이서연     B
2  박지호     A
3  최수아     C
4  정민서     B

086. 옆으로 이어 붙이기

students와 scores의 kor, eng를 옆으로 붙이세요(행 순서가 같다고 가정).

정답 보기
Pythonpd.concat([students, scores[['kor', 'eng']]], axis=1)
결과     name class  kor  eng
0  김민준     A   85   78
1  이서연     B   92   88
2  박지호     A   58   64
3  최수아     C   77   95

087. 넓은 표를 길게

scores를 student, subject, score 세 열의 긴 표로 바꾸세요.

정답 보기
Pythonlong = scores.melt(id_vars='student', var_name='subject', value_name='score')
long
결과  student subject  score
0  김민준     kor     85
1  이서연     kor     92
2  박지호     kor     58
3  최수아     kor     77
4  김민준     eng     78
5  이서연     eng     88
6  박지호     eng     64
7  최수아     eng     95

088. 긴 표를 넓게

87번의 긴 표를 다시 학생별 과목 열로 펼치세요.

정답 보기
Pythonlong.pivot(index='student', columns='subject', values='score')
결과subject  eng  kor
student          
김민준    78   85
박지호    64   58
이서연    88   92
최수아    95   77

089. 교차표

students의 반별 학생 수를 교차표로 구하세요(동아리 가입 여부와 함께).

정답 보기
Pythonjoined = students.merge(clubs, on='name', how='left')
pd.crosstab(joined['class'], joined['club'].notna().map({True: '가입', False: '미가입'}))
결과club   가입  미가입
class              
A         2       0
B         0       1
C         0       1

090. 리스트를 행으로 펼치기

tags 열의 리스트를 행 단위로 펼치세요.

정답 보기
Pythont = pd.DataFrame({'post': [1, 2], 'tags': [['pandas', 'python'], ['sql']]})
t.explode('tags')
결과   post    tags
0     1  pandas
0     1  python
1     2     sql

전체 메뉴