320x100
이번에도 호흡은 길다.
하지만 원리가 생각보다 단조로워서 어렵진 않았다.
다만, 흐름이 끊길일들이 너무 많았다.
대표적으로 허벅지를 고름이 많이 고여있어서 새끼손가락 반마디만큼 째고,
아직도 곪아있는게 남아있다는 이유로 1주일이 넘게 꼬매지 않고 있다;
이런일이 실제로 있을 줄이야...
걸을때마다 다리 안에서 벌레가 기어다니는 느낌이다..
아무튼! 본론으로 돌아와서!
# Merging, Joining and Concatenating DataFrames
## Adding / concatenating Rows (Part 1)
import pandas as pd
men2004 = pd.read_csv('men2004.csv')
men2004.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
2 SCHOEMAN, Roland 3
3 PEIRSOL, Aaron 3
4 CROCKER, Ian 3
'''
men2008 = pd.read_csv('men2008.csv')
men2008.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
'''
# 2004년 데이터프레임에 2008년의 모든 데이터프레임을 이어붙이기
# 방법1 append
men2004.append(men2008, ignore_index= True)
# 2004년 데이터프레임에 2008년의 모든 데이터프레임을 이어붙이기
# 방법2 concat
pd.concat([men2004, men2008], ignore_index = True, keys = None)
# axis의 기본값이 0 즉, 행(가로)을 기준으로 설정되어있다.
# 만약 axis를 1롤 설정해준다면 열(세로)를 기준으로 설정되기 때문에
# A라는 데이터 프레임의 마지막을 기준으로 오른쪽으로 B라는 데이터 프레임을 붙이는 것이 가능하다.
# concat에서 keys는 메인 행 인덱스를 구분해주는 역할을 한다.
# 따라서 이걸 잘 써주면, ignore_index가 필요가 없다.
pd.concat([men2004, men2008], keys = [2004,2008])
'''
Athlete Medals
2004 0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ... ...
2008 60 MALLET, Gregory 1
61 ZHANG, Lin 1
121 rows × 2 columns
'''
# 즉, 뿌리, 줄기의 통계 개념과 같이 keys는 뿌리를 만들어주는 역할을 한다.
# 뿌리와 줄기개념은 '멀티 인덱스'라고 불린다.
# 만약, 뿌리별로 행 인덱스값이 1~마지막, 다음 뿌리에서 1~ 마지막이 되길 원한다면 ignore_index를 안써줘도 된다.
# 하지만 뿌리별로 구분이 되더라도, 전체 행 인덱스 값은 통일해서 1부터 마지막까지 원큐에 가길 원한다면 ignore_index = True를 해줘야한다.
# 고 생각할 수 있다.
pd.concat([men2004, men2008], ignore_index = True, keys = [2004, 2008])
# 하지만 이와같이 ignore_index = True를 해주면 keys에 입력된 값은 무용지물이 된다.
'''
Athlete Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ...
119 MALLET, Gregory 1
120 ZHANG, Lin 1
121 rows × 2 columns
'''
men0408 = pd.concat([men2004,men2008], ignore_index = False, keys = [2004,2008], names = ['Year'])
'''
Athlete Medals
Year
2004 0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ... ...
2008 60 MALLET, Gregory 1
61 ZHANG, Lin 1
121 rows × 2 columns
'''
# 멀티인덱스 및 keys를 작동시키려면 ignore_index 를 False로 주거나, 아예 입력을 하지 말아야지 작동됨을 명심하자.
men0408
'''
Athlete Medals
Year
2004 0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ... ...
2008 60 MALLET, Gregory 1
61 ZHANG, Lin 1
121 rows × 2 columns
'''
men0408.reset_index()
'''
Year level_1 Athlete Medals
0 2004 0 PHELPS, Michael 8
1 2004 1 THORPE, Ian 4
... ... ... ... ...
119 2008 60 MALLET, Gregory 1
120 2008 61 ZHANG, Lin 1
121 rows × 4 columns
'''
# 최종적으로 기존의 컬럼 중 한개를 지우기
men0408.reset_index().drop(columns = ['level_1'])
'''
Year Athlete Medals
0 2004 PHELPS, Michael 8
1 2004 THORPE, Ian 4
... ... ... ...
120 2008 ZHANG, Lin 1
121 rows × 3 columns
'''
# 하지만 inplace True나 오버라이트가 안되었기에 딱히 저장은 되지 않는다.
## Adding / Concatenating Rows (Part2)
men2004.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
2 SCHOEMAN, Roland 3
3 PEIRSOL, Aaron 3
4 CROCKER, Ian 3
'''
men2008.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
'''
# 컬럼명 변경
men2004.columns = ['Name', 'Medals']
men2004
'''
Name Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ...
57 MAGNINI, Filippo 1
58 ZWERING, Klaas-Erik 1
59 rows × 2 columns
'''
# 새 컬럼및 값 추가
# 새 컬럼 추가
# 새 컬럼 값 추가
men2004['Success'] = 'Yes'
men2004
'''
Name Medals Success
0 PHELPS, Michael 8 Yes
1 THORPE, Ian 4 Yes
... ... ... ...
57 MAGNINI, Filippo 1 Yes
58 ZWERING, Klaas-Erik 1 Yes
59 rows × 3 columns
'''
# names에 주어지는 값은 컬럼값에 입력된다. 순서대로.
# 한개만 입력되면 첫번째 컬럼값인 한개만 변경된다.
pd.concat([men2004, men2008], keys = [2004, 2008], names = ['Year'])
# labels은 컬럼값이나 마찬가지다. 거기다가 axis =1이니 반드시 컬럼이고
# 그것을 drop 하는 것이다.
men2004.drop(labels = ['Success'], axis = 1, inplace = True)
men2004
'''
Name Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ...
57 MAGNINI, Filippo 1
58 ZWERING, Klaas-Erik 1
59 rows × 2 columns
'''
# men 2008의 컬럼 값을 men2004의 컬럼값과 동일하게 한다. 라는 의미다.
# 다만, 각 컬럼의 갯수는 일치해야 활용 되는 것으로 알고있다.
men2008.columns = men2004.columns
men2008.head()
'''
Name Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
'''
# 기존의 Athlete, Medals 컬럼 명이 Name, Medals로 변경되었다.
pd.concat([men2004, men2008], keys = [2004,2008], names = ['Year'])
'''
Name Medals
Year
2004 0 PHELPS, Michael 8
1 THORPE, Ian 4
... ... ... ...
2008 60 MALLET, Gregory 1
61 ZHANG, Lin 1
121 rows × 2 columns
'''
# 이제는 concat으로 합쳐주었을때, NaN같이 불일치로 인한 결측값이 생기지는 않는다.
# 둘다 재 import 해오는데, Athlete를 기준 인덱스로 잡아준다.
men2004 = pd.read_csv('men2004.csv', index_col = 'Athlete')
men2008 = pd.read_csv('men2008.csv', index_col = 'Athlete')
men2004.head()
'''
Medals
Athlete
PHELPS, Michael 8
THORPE, Ian 4
SCHOEMAN, Roland 3
PEIRSOL, Aaron 3
CROCKER, Ian 3
'''
# 기존에 기준인덱스로써 Athlete가 설정 되어있다.
# 이때 concat을 사용하고, ignore_index = True를 해주게되면
# 기존에 설정되어있던 부가 값들, 이를테면 기준인덱스 등에 대해서 모두 날아가게 된다.
pd.concat([men2004, men2008], ignore_index = True, keys = [2004, 2008])
'''
Medals
0 8
1 4
... ...
119 1
120 1
121 rows × 1 columns
'''
## Arithmetic between Pandas Objects / Data Alignment
import pandas as pd
topfive_2004 = pd.read_csv('topfive_2004.csv', index_col = 'Athlete')
topfive_2008 = pd.read_csv('topfive_2008.csv', index_col = 'Athlete')
topfive_2004
'''
Gold Silver Bronze
Athlete
PHELPS, Michael 6.0 0.0 2.0
PEIRSOL, Aaron 3.0 0.0 0.0
THORPE, Ian 2.0 1.0 1.0
KITAJIMA, Kosuke 2.0 0.0 1.0
HACKETT, Grant 1.0 2.0 0.0
'''
topfive_2008
'''
Gold Silver bronze
Athlete
PHELPS, Michael 8.0 0.0 0.0
GREVERS, Matt 2.0 1.0 0.0
PEIRSOL, Aaron 2.0 1.0 0.0
LOCHTE, Ryan 2.0 0.0 2.0
KITAJIMA, Kosuke 2.0 0.0 1.0
'''
topfive_2004 + topfive_2008
'''
Bronze Gold Silver bronze
Athlete
GREVERS, Matt NaN NaN NaN NaN
HACKETT, Grant NaN NaN NaN NaN
KITAJIMA, Kosuke NaN 4.0 0.0 NaN
LOCHTE, Ryan NaN NaN NaN NaN
PEIRSOL, Aaron NaN 5.0 1.0 NaN
PHELPS, Michael NaN 14.0 0.0 NaN
THORPE, Ian NaN NaN NaN NaN
'''
# 이렇듯, 연산은 일종의 concat과 같은 기능을 하는 것으로 보인다.
# 그렇기에 서로의 데이터프레임에 겹치는 내용이 많이 없을 수록 결측값이 많이 생긴다.
# 결측치에 대한 팁****
# 결측치는 기존의 topfive_2004에서 가지고 있던 것들이 +연산 이후에 결측값으로써 없어지는 경우가 있다.
# 어느 한쪽에만 있는값인 경우에 그렇다.
# 연산하고자 하는 모든 데이터프레임에 값이 있어야 비로소 연산이되고 값이 출력된다.
# 따라서, 두 데이터 프레임 모두에만 값이 있는 경우가 6개다.
# 모든 데이터 프레임에 해당 행 인덱스의 내용이 없는 경우에 결측값이 생겼다.
# 이것을 방지 하기 위하여 사용하는 것이 add다.
topfive_2004.add(topfive_2008)
'''
Bronze Gold Silver bronze
Athlete
GREVERS, Matt NaN NaN NaN NaN
HACKETT, Grant NaN NaN NaN NaN
KITAJIMA, Kosuke NaN 4.0 0.0 NaN
LOCHTE, Ryan NaN NaN NaN NaN
PEIRSOL, Aaron NaN 5.0 1.0 NaN
PHELPS, Michael NaN 14.0 0.0 NaN
THORPE, Ian NaN NaN NaN NaN
'''
# 여기까진 똑같다.
# 컬럼명 변경
topfive_2008.rename(columns = {'bronze':'Bronze'}, inplace = True)
# fill_value는 NaN 즉, 결측값을 대신하여 넣어주는 값이다.
topfive_2004.add(topfive_2008, fill_value = 0)
'''
Gold Silver Bronze
Athlete
GREVERS, Matt 2.0 1.0 0.0
HACKETT, Grant 1.0 2.0 0.0
KITAJIMA, Kosuke 4.0 0.0 2.0
LOCHTE, Ryan 2.0 0.0 2.0
PEIRSOL, Aaron 5.0 1.0 0.0
PHELPS, Michael 14.0 0.0 2.0
THORPE, Ian 2.0 1.0 1.0
'''
# 여기서는 sub로써 뺄셈을 해주는 것을
# 전년도와 올해를 비교하여 성장을 나타내주는 수치로 표현해주기도 했다.
topfive_2004.sub(topfive_2008, fill_value = 0)
'''
Gold Silver Bronze
Athlete
GREVERS, Matt -2.0 -1.0 0.0
HACKETT, Grant 1.0 2.0 0.0
KITAJIMA, Kosuke 0.0 0.0 0.0
LOCHTE, Ryan -2.0 0.0 -2.0
PEIRSOL, Aaron 1.0 -1.0 0.0
PHELPS, Michael -2.0 0.0 2.0
THORPE, Ian 2.0 1.0 1.0
'''
## Outer Join
- outer join은 합집합 개념이다.
import pandas as pd
men2004 = pd.read_csv('men2004.csv')
men2008 = pd.read_csv('men2008.csv')
men2004.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
2 SCHOEMAN, Roland 3
3 PEIRSOL, Aaron 3
4 CROCKER, Ian 3
'''
men2008.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
'''
men2008.shape
# (62, 2)
len(men2004) + len(men2008)
# 121
# 여기서 men2008은 right 에 해당 하는 값을 넣어준 것이다.
# outer join에 있어서 자동적으로 men2004는 left 측면이 되는 것이기 때문이다.
# right 측면은 join하길 원하는 부분이다.
# 결과적으로 outer join은 단 하나의 값이라도 어느 하나에 속하게 되면 join된다. or 조건이라고 보면 된다.
men2004.merge(men2008, how = 'outer', on = 'Athlete')
'''
Athlete Medals_x Medals_y
0 PHELPS, Michael 8.0 8.0
1 THORPE, Ian 4.0 NaN
2 SCHOEMAN, Roland 3.0 NaN
3 PEIRSOL, Aaron 3.0 3.0
4 CROCKER, Ian 3.0 1.0
... ... ... ...
100 LAGUNOV, Evgeniy NaN 1.0
101 BERENS, Ricky NaN 1.0
102 LURZ, Thomas NaN 1.0
103 MALLET, Gregory NaN 1.0
104 ZHANG, Lin NaN 1.0
105 rows × 3 columns
'''
# suffixes 매개변수를 통해서 Medals_x, Medals_y의 값을 변경해 줄 수 있다.
# on 매개변수는 '라벨 인덱스'라고는 하는데, 정확한 사용 기능은 잘 모르겠다.
men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes =['_2004', '_2008'])
'''
Athlete Medals_2004 Medals_2008
0 PHELPS, Michael 8.0 8.0
1 THORPE, Ian 4.0 NaN
2 SCHOEMAN, Roland 3.0 NaN
3 PEIRSOL, Aaron 3.0 3.0
4 CROCKER, Ian 3.0 1.0
... ... ... ...
100 LAGUNOV, Evgeniy NaN 1.0
101 BERENS, Ricky NaN 1.0
102 LURZ, Thomas NaN 1.0
103 MALLET, Gregory NaN 1.0
104 ZHANG, Lin NaN 1.0
105 rows × 3 columns
'''
# 재미있는 결과로는 suffixes 값에 있어서 _2004, _2008로 입력해주었는데
# 각각 고유로 가지고 있던 컬럼 명+ suffixes 값으로 출력 되었다.
# indicator 매개변수를 통해서 merge의 결과값이 어디로 부터 비롯되었는지 확인할 수 있다.
men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes=['_2004', '_2008'], indicator = True)
'''
Athlete Medals_2004 Medals_2008 _merge
0 PHELPS, Michael 8.0 8.0 both
1 THORPE, Ian 4.0 NaN left_only
2 SCHOEMAN, Roland 3.0 NaN left_only
3 PEIRSOL, Aaron 3.0 3.0 both
4 CROCKER, Ian 3.0 1.0 both
... ... ... ... ...
100 LAGUNOV, Evgeniy NaN 1.0 right_only
101 BERENS, Ricky NaN 1.0 right_only
102 LURZ, Thomas NaN 1.0 right_only
103 MALLET, Gregory NaN 1.0 right_only
104 ZHANG, Lin NaN 1.0 right_only
105 rows × 4 columns
'''
men0408 = men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes=['_2004', '_2008'], indicator=True)
men0408._merge.value_counts()
'''
right_only 46
left_only 43
both 16
Name: _merge, dtype: int64
'''
# outer join 해줄때, 왼쪽은 2004년도, 오른쪽은 2008년도의 메달 수상 기록이 있었다.
# 즉, right_only는 2008년 수상자를 의미하고
# left_only는 2004년 수상자를 의미하고
# both는 두 해에 모두 수상한 기록을 의미한다.
## Inner Join
- inner join은 교집합 개념이다.
men2004.merge(men2008, how = 'inner', on = 'Athlete', suffixes= ['_2004', '_2008'], indicator= True)
'''
Athlete Medals_2004 Medals_2008 _merge
0 PHELPS, Michael 8 8 both
1 PEIRSOL, Aaron 3 3 both
2 CROCKER, Ian 3 1 both
3 KITAJIMA, Kosuke 3 3 both
4 HANSEN, Brendan 3 1 both
5 HACKETT, Grant 3 2 both
6 LEZAK, Jason 2 3 both
7 KELLER, Klete 2 1 both
8 LOCHTE, Ryan 2 4 both
9 VENDT, Erik 1 1 both
10 VANDERKAAY, Peter 1 2 both
11 CSEH, Laszlo 1 3 both
12 DAVIES, David 1 1 both
13 DUBOSCQ, Hugues 1 2 both
14 GANGLOFF, Mark 1 1 both
15 JENSEN, Larsen 1 1 both
'''
# 결국, outer join의 마지막에
# men0408._merge.value_counts()
# 를 실행해주었을때를 보면, both가 16회였다.
# 이처럼 both로 함께 되어있는 것만 출력 되는게 inner join이다.
## Outer Join without Intersection
- 교집합을 제외한 합집합
import pandas as pd
men2004 = pd.read_csv('men2004.csv')
men2008 = pd.read_csv('men2008.csv')
men0408 = men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes= ('_2004', '_2008'), indicator = True)
# 이 값은 합집합의 변수다.
# 따라서, 이제 합집합 뿐만 아닌, 합집합 안의 교집합을 제거해준다.
men0408
# 교집합을 제거하기 위한 필터링 작업
men0408._merge != 'both'
'''
0 False
1 True
2 True
3 False
4 False
...
100 True
101 True
102 True
103 True
104 True
Name: _merge, Length: 105, dtype: bool
'''
# 교집합 제거를 위한 필터링 적용
men0408.loc[men0408._merge != 'both']
'''
Athlete Medals_2004 Medals_2008 _merge
1 THORPE, Ian 4.0 NaN left_only
2 SCHOEMAN, Roland 3.0 NaN left_only
7 VAN DEN HOOGENBAND, Pieter 3.0 NaN left_only
9 MORITA, Tomomi 2.0 NaN left_only
11 ROGAN, Markus 2.0 NaN left_only
... ... ... ... ...
100 LAGUNOV, Evgeniy NaN 1.0 right_only
101 BERENS, Ricky NaN 1.0 right_only
102 LURZ, Thomas NaN 1.0 right_only
103 MALLET, Gregory NaN 1.0 right_only
104 ZHANG, Lin NaN 1.0 right_only
89 rows × 4 columns
'''
## Left Join without Intersection
- 오직 왼쪽의 벤다이어그램만.
- 왼쪽의 벤다이어그램 중에서도 교집합 부분을 제외하고 순수 왼쪽 벤다이어그램이 가지고 있는 값만.
men0408 = men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes=('_2004', '_2008'), indicator = True)
men0408.head()
'''
Athlete Medals_2004 Medals_2008 _merge
0 PHELPS, Michael 8.0 8.0 both
1 THORPE, Ian 4.0 NaN left_only
2 SCHOEMAN, Roland 3.0 NaN left_only
3 PEIRSOL, Aaron 3.0 3.0 both
4 CROCKER, Ian 3.0 1.0 both
'''
men0408.loc[men0408._merge == 'left_only']
'''
Athlete Medals_2004 Medals_2008 _merge
1 THORPE, Ian 4.0 NaN left_only
2 SCHOEMAN, Roland 3.0 NaN left_only
7 VAN DEN HOOGENBAND, Pieter 3.0 NaN left_only
9 MORITA, Tomomi 2.0 NaN left_only
11 ROGAN, Markus 2.0 NaN left_only
...
'''
# 밑에도 값이 주르륵 있지만, 마지막에 00rows * 00 뭐 그런 안내가 없다.
# 그럴 경우 일일이 세면 시간도 문제지만, 정확도의 문제가 생길 수 있다.
# 그것을 방지해주기 위해서
men0408[men0408._merge == 'left_only'].shape
# (43, 4)
# 이렇게 해주면 rows는 43개, 즉, 43개의 값을 가졌다는 것을 알 수 있고
# columns 는 4임을 알 수 있다.
## Right Join without Intersection
# 내가 풀어본 문제.
men0408 = men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes = ['_2004', '_2008'], indicator = True)
test = men2004.merge(men2008, how = 'right', suffixes=['_2004', '_2008'], indicator= True)
right_join = test.loc[test._merge != 'both']
right_join.shape
# (55, 3)
# 결과적으로 46이 나와야하는데, 왜 55일까.
# 그래도 내꺼는 출력해보면 모두 right_only로 나오는데 말이다.
# 답안 코드
men0408 = men2004.merge(men2008, how = 'outer', on = 'Athlete',suffixes= ['_2004', '_2008'], indicator= True)
# 만약에 결과값이 다르다면 생각해볼 수 있는 단서는 사실 1가지 뿐이다.
# on을 나는 써주지 않았다. on 지정이 결과값에 미치는 영향이 있을 것같다.
# 추측이 맞는것 같다. on을 써주지 않았던 샘플 변수였던 test는 on을 안붙여 줬기에
# medal이라고 통틀어서 나온다. 몇년도 메달, 몇년도 메달이 아니라.
check = men0408.loc[men0408._merge == 'right_only']
'''
Athlete Medals_2004 Medals_2008 _merge
59 BERNARD, Alain NaN 3.0 right_only
60 SULLIVAN, Eamon NaN 3.0 right_only
61 LAUTERSTEIN, Andrew NaN 3.0 right_only
62 GREVERS, Matt NaN 3.0 right_only
63 RICKARD, Brenton NaN 2.0 right_only
64 LEVEAUX, Amaury NaN 2.0 right_only
...
'''
check.shape
# (46, 4)
# 결과값에 있어서 내가 원하던 결과 값이다.
## Left Join
# 내코드
# 이번엔 맞는 것 같다.
test = men2004.merge(men2008, how = 'left', on = 'Athlete', suffixes=['_2004', '_2008'], indicator=True)
'''
Athlete Medals_2004 Medals_2008 _merge
0 PHELPS, Michael 8 8.0 both
1 THORPE, Ian 4 NaN left_only
2 SCHOEMAN, Roland 3 NaN left_only
3 PEIRSOL, Aaron 3 3.0 both
4 CROCKER, Ian 3 1.0 both
'''
# on을 해주어서 이젠 맞게 온것 같다.
test.loc[test._merge == 'left_only']
'''
Athlete Medals_2004 Medals_2008 _merge
1 THORPE, Ian 4 NaN left_only
2 SCHOEMAN, Roland 3 NaN left_only
7 VAN DEN HOOGENBAND, Pieter 3 NaN left_only
9 MORITA, Tomomi 2 NaN left_only
'''
test.loc[test._merge == 'left_only'].shape
# (43, 4)
# 아니다. 결과적으로 순수한 왼쪽 벤다이어그램 값으로만 결과를 만들었다. 교집합을 제외한 수로.
# 다시해보자.
test.shape
# (59, 4)
# 음.. 사실상 처음에 merge시켜줄때 left해준것만으로도 끝이나 다름없다.
## Right join
# 내 코드
men2004.merge(men2008, how = 'right', on = 'Athlete', suffixes = ['_2004', '_2008'], indicator = True)
# 사실상 이걸로 끝이다.
# 답안 코드
men2004.merge(men2008, how = 'right', on = 'Athlete', suffixes=['_2004', '_2008'], indicator=True)
# 벤다이어그램 A와 B의 위치를 전환하여 표현
men2008.merge(men2004, how = 'left', on = 'Athlete', suffixes=['_2008', '_2004'], indicator=True)
## Joining on different Column Labels & Indexes
import pandas as pd
men2004 = pd.read_csv('men2004.csv')
men2008 = pd.read_csv('men2008.csv')
men2008.head()
'''
Athlete Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
'''
men2004.columns = ['Name', 'Medals']
men2004.head()
'''
Name Medals
0 PHELPS, Michael 8
1 THORPE, Ian 4
2 SCHOEMAN, Roland 3
3 PEIRSOL, Aaron 3
4 CROCKER, Ian 3
'''
men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes= ['_2004', '_2008'], indicator=True)
# KeyError가 난다.
# men2004의 컬럼명을 변경해주었기에 men2008의 'Athlete'와 맞지 않는다.
# merge를 할때 on을 설정해놓으면, 둘의 컬럼명, 컬럼수가 반드시 일치해야지 진행이 된다.
# 즉, on을 조작해주면 굳이 컬럼명, 컬럼수가 일치할 필요는 없다는 의미다.
# 만약 위의 경우처럼 컬럼명, 컬럼 수가 다를 경우엔
# merge를 해줄 기준값을 설정해주어야 한다. 왼쪽과 오른쪽 각각에 말이다.
men0408 = men2004.merge(men2008, how = 'outer', left_on = 'Name', right_on = 'Athlete', suffixes=['_2004', '_2008'], indicator=True)
'''
Name Medals_2004 Athlete Medals_2008 _merge
0 PHELPS, Michael 8.0 PHELPS, Michael 8.0 both
1 THORPE, Ian 4.0 NaN NaN left_only
2 SCHOEMAN, Roland 3.0 NaN NaN left_only
3 PEIRSOL, Aaron 3.0 PEIRSOL, Aaron 3.0 both
4 CROCKER, Ian 3.0 CROCKER, Ian 1.0 both
'''
# 각각 컬럼명이 다른 것을 merge해 줌으로 인해서 결측값이 중간중간에 많이 생긴다.
# 결측값을 없애주기 위해서 fillna()를 사용해준다.
# 결측값 채워넣기
# 결측값을 다른 값으로 채워넣기
men0408.Name.fillna(men0408.Athlete, inplace=True)
'''
0 PHELPS, Michael
1 THORPE, Ian
2 SCHOEMAN, Roland
3 PEIRSOL, Aaron
4 CROCKER, Ian
...
100 LAGUNOV, Evgeniy
101 BERENS, Ricky
102 LURZ, Thomas
103 MALLET, Gregory
104 ZHANG, Lin
Name: Name, Length: 105, dtype: object
'''
# fillna 메서드에서는 간단하게
# "결측값"자리에 무엇을 입력해줄래? 라고 묻는것이고
# 여기서는 '그 자리에 men0408.Athlete'를 넣을래. 라고 표현해준것이다.
men0408.head()
'''
Name Medals_2004 Athlete Medals_2008 _merge
0 PHELPS, Michael 8.0 PHELPS, Michael 8.0 both
1 THORPE, Ian 4.0 NaN NaN left_only
2 SCHOEMAN, Roland 3.0 NaN NaN left_only
3 PEIRSOL, Aaron 3.0 PEIRSOL, Aaron 3.0 both
4 CROCKER, Ian 3.0 CROCKER, Ian 1.0 both
'''
# 이제 결측값을 대신하여 Athlete 값도 채워주었으니, 무의미한 컬럼을 지워주자.
men0408.drop(['Athlete', '_merge'], axis = 1, inplace = True)
'''
Name Medals_2004 Medals_2008
0 PHELPS, Michael 8.0 8.0
1 THORPE, Ian 4.0 NaN
2 SCHOEMAN, Roland 3.0 NaN
3 PEIRSOL, Aaron 3.0 3.0
4 CROCKER, Ian 3.0 1.0
... ... ... ...
100 LAGUNOV, Evgeniy NaN 1.0
101 BERENS, Ricky NaN 1.0
102 LURZ, Thomas NaN 1.0
103 MALLET, Gregory NaN 1.0
104 ZHANG, Lin NaN 1.0
105 rows × 3 columns
'''
men2008
'''
Athlete Medals
0 PHELPS, Michael 8
1 LOCHTE, Ryan 4
2 BERNARD, Alain 3
3 SULLIVAN, Eamon 3
4 LAUTERSTEIN, Andrew 3
... ... ...
57 LAGUNOV, Evgeniy 1
58 BERENS, Ricky 1
59 LURZ, Thomas 1
60 MALLET, Gregory 1
61 ZHANG, Lin 1
62 rows × 2 columns
'''
men2008.set_index('Athlete', inplace = True)
men2008.head()
'''
Medals
Athlete
PHELPS, Michael 8
LOCHTE, Ryan 4
BERNARD, Alain 3
SULLIVAN, Eamon 3
LAUTERSTEIN, Andrew 3
'''
men2004.merge(men2008, how = 'outer', left_on = 'Name', right_on = 'Athlete',
suffixes=['_2004', '_2008'], indicator= True)
'''
Name Medals_2004 Medals_2008 _merge
0 PHELPS, Michael 8.0 8.0 both
1 THORPE, Ian 4.0 NaN left_only
2 SCHOEMAN, Roland 3.0 NaN left_only
3 PEIRSOL, Aaron 3.0 3.0 both
4 CROCKER, Ian 3.0 1.0 both
... ... ... ... ...
100 NaN NaN 1.0 right_only
101 NaN NaN 1.0 right_only
102 NaN NaN 1.0 right_only
103 NaN NaN 1.0 right_only
104 NaN NaN 1.0 right_only
105 rows × 4 columns
1
'''
men2004.merge(men2008, how = 'outer', left_on = 'Name', right_index = True ,
suffixes= ['_2004', '_2008'], indicator= True)
## Joining on many Columns
import pandas as pd
men2004_det = pd.read_csv("men2004_det.csv")
men2008_det = pd.read_csv('men2008_det.csv')
men2004_det.head(10)
'''
Athlete Medal Count
0 BOVELL, George Bronze 1
1 BREMBILLA, Emiliano Bronze 1
2 CAPPELLAZZO, Federico Bronze 1
3 CERCATO, Simone Bronze 1
4 CONRAD, Lars Silver 1
5 CROCKER, Ian Bronze 1
6 CROCKER, Ian Gold 1
7 CROCKER, Ian Silver 1
8 CSEH, Laszlo Bronze 1
9 DAVIES, David Bronze 1
'''
men2008_det.head(10)
'''
Athlete Medal Count
0 ADRIAN, Nathan Gold 1
1 BERENS, Ricky Gold 1
2 BERNARD, Alain Bronze 1
3 BERNARD, Alain Gold 1
4 BERNARD, Alain Silver 1
5 BOUSQUET, Frederick Silver 1
6 BRITS, Grant Bronze 1
7 BRODIE, Leith Bronze 2
8 CALLUS, Ashley Bronze 1
9 CAVIC, Milorad Silver 1
'''
men2004_det.loc[men2004_det.Athlete == 'PHELPS, Michael']
'''
Athlete Medal Count
50 PHELPS, Michael Bronze 2
51 PHELPS, Michael Gold 6
'''
men2008_det.loc[men2008_det.Athlete == 'PHELPS, Michael']
'''
Athlete Medal Count
54 PHELPS, Michael Gold 8
'''
men0408 = men2004_det.merge(men2008_det, how = 'outer', on = 'Athlete', suffixes=['_2004', '_2008'])
'''
Athlete Medal_2004 Count_2004 Medal_2008 Count_2008
0 BOVELL, George Bronze 1.0 NaN NaN
1 BREMBILLA, Emiliano Bronze 1.0 NaN NaN
2 CAPPELLAZZO, Federico Bronze 1.0 NaN NaN
3 CERCATO, Simone Bronze 1.0 NaN NaN
4 CONRAD, Lars Silver 1.0 NaN NaN
... ... ... ... ... ...
137 VYATCHANIN, Arkady NaN NaN Bronze 2.0
138 WALTERS, David NaN NaN Gold 1.0
139 WEBER-GALE, Garrett NaN NaN Gold 2.0
140 WILDMAN-TOBRINER, Ben NaN NaN Gold 1.0
141 ZHANG, Lin NaN NaN Silver 1.0
142 rows × 5 columns
'''
men0408.loc[men0408.Athlete == 'PHELPS, Michael']
'''
Athlete Medal_2004 Count_2004 Medal_2008 Count_2008
59 PHELPS, Michael Bronze 2.0 Gold 8.0
60 PHELPS, Michael Gold 6.0 Gold 8.0
'''
## pd.merge and join()
import pandas as pd
men2004 = pd.read_csv('men2004.csv', index_col = 'Athlete')
men2008 = pd.read_csv('men2008.csv', index_col = 'Athlete')
men2004.head()
'''
Medals
Athlete
PHELPS, Michael 8
THORPE, Ian 4
SCHOEMAN, Roland 3
PEIRSOL, Aaron 3
CROCKER, Ian 3
'''
men2008.head()
'''
Medals
Athlete
PHELPS, Michael 8
LOCHTE, Ryan 4
BERNARD, Alain 3
SULLIVAN, Eamon 3
LAUTERSTEIN, Andrew 3
'''
men2004.merge(men2008, how = 'outer', on = 'Athlete', suffixes= ['_2004', '_2008'], indicator=True)
'''
Medals_2004 Medals_2008 _merge
Athlete
PHELPS, Michael 8.0 8.0 both
THORPE, Ian 4.0 NaN left_only
SCHOEMAN, Roland 3.0 NaN left_only
PEIRSOL, Aaron 3.0 3.0 both
CROCKER, Ian 3.0 1.0 both
... ... ... ...
LAGUNOV, Evgeniy NaN 1.0 right_only
BERENS, Ricky NaN 1.0 right_only
LURZ, Thomas NaN 1.0 right_only
MALLET, Gregory NaN 1.0 right_only
ZHANG, Lin NaN 1.0 right_only
105 rows × 3 columns
'''
pd.merge(men2004, men2008, how = 'outer', on = 'Athlete', suffixes= ['_2004', '_2008'], indicator= True)
'''
Medals_2004 Medals_2008 _merge
Athlete
PHELPS, Michael 8.0 8.0 both
THORPE, Ian 4.0 NaN left_only
SCHOEMAN, Roland 3.0 NaN left_only
PEIRSOL, Aaron 3.0 3.0 both
CROCKER, Ian 3.0 1.0 both
... ... ... ...
LAGUNOV, Evgeniy NaN 1.0 right_only
BERENS, Ricky NaN 1.0 right_only
LURZ, Thomas NaN 1.0 right_only
MALLET, Gregory NaN 1.0 right_only
ZHANG, Lin NaN 1.0 right_only
105 rows × 3 columns
'''
men2004.join(men2008, how = 'outer', lsuffix= '_2004', rsuffix='_2008')
'''
Medals_2004 Medals_2008
Athlete
ADRIAN, Nathan NaN 1.0
BERENS, Ricky NaN 1.0
BERNARD, Alain NaN 3.0
BOUSQUET, Frederick NaN 1.0
BOVELL, George 1.0 NaN
... ... ...
WOODWARD, Gabe 1.0 NaN
YAMAMOTO, Takashi 2.0 NaN
ZASTROW, Mitja 1.0 NaN
ZHANG, Lin NaN 1.0
ZWERING, Klaas-Erik 1.0 NaN
105 rows × 2 columns
'''
300x250
'개발일지 > Pandas' 카테고리의 다른 글
pandas 판다스 기초 19 groupby, relabeling, aggregation, transform, apply, stack (0) | 2022.08.12 |
---|---|
pandas 틀린부분 복기8 merge, add, 등 2개 이상의 파일 붙이고, 가공하기 (0) | 2022.08.08 |
pandas 판다스 틀린부분 복기 7 데이터 정리하기 (0) | 2022.08.01 |
매우중요 pandas 판다스 기초 17 결측값(NaN), 중복값(duplicated) 활용 (0) | 2022.07.29 |
pandas 판다스 문자열 가공 혼자서 해보기 (0) | 2022.07.28 |