본문 바로가기
데이터분석/Pandas

[Python] Pandas 11 _ pandas_m&a

by nemonemonemo 2025. 8. 21.

기본적으로 1개의 DF이 아니라 여러개의 흩어져있는 DF에 있는 정보를 합쳐서 진행하는 과정

⇒ sql에서 join과 매우 유사함

  • 방식1) 단순하게 이어 붙이는 연결’
    • 옆으로 이어 붙이기 (속성이 늘어나는 것)
    • 밑으로 이어 붙이기 (샘플의 수가 늘어나는 것)
    • ⇒ .append(아래로 붙이는 메서드) → 요즘은 concat으로 통합함
    • FM적인 방법 : concat(axis = 0/1)
      • pd.concat([합칠 DF1, 합칠 DF2, ….])
      • axis = 0/1
      • inplace_index = T/F
        • 합치다보면 기존 인덱스들이 중첩/꼬일 수 도 있음
        • 기존것을 싹 무시하고 0~n까지 정수 부여
  • 방식2) 특정 조건에 맞는 연결 (sql 에서 join — pandas에서 pd.merge)

++리스트는 가로 중심, 딕셔너리는 세로 중심

리스트 가로 중심
딕셔너리 세로 중심

#1 
import pandas as pd

# --> 샘플 데이터 생성
df1 = pd.DataFrame(
    {
        "A":["A0","A1","A2","A3"],
        "B":["B0","B1","B2","B3"],
        "C":["C0","C1","C2","C3"],
        "D":["D0","D1","D2","D3"]
    },
    index=[0,1,2,3]
)

df1
'''

  A	  B	  C  	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3

'''

# ==> 샘플 데이터를 생성!!~
df2 = pd.DataFrame(
    {
        "A":["A4","A5","A6","A7"],
        "B":["B4","B5","B6","B7"],
        "C":["C4","C5","C6","C7"],
        "D":["D4","D5","D6","D7"]
    },
    index=[4,5,6,7]
)
df2
'''

   A	 B	 C	D
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7

'''

상황 : 2개의 서로 다른 DF이 존재

  • 가로줄에 대한 인덱스 : 서로 완전 다른
  • 세로줄에 대한 인덱스(컬럼명) : 서로 동일함

⇒ 각 부서별/지점별 양식 파일을 만들어서 배포 ⇒ 각 부서/지점에서 작성하고,,본사에서 취합!!!!

pd.concat( [df1, df2])
'''
	 A	 B	 C	 D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7

'''

pd.concat( [df2, df1]) # --> 합칠 대상들을 순서대로 합쳐주는 역할!!!
'''
	 A	 B	C	  D
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
'''

# ** 합칠 대상들을 어떤 순서대로 쌓을지 생각을 하고, 리스트업!!!

pd.concat( [df1, df2], axis=0)
'''
	 A	 B	 C	 D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7

'''
pd.concat( [df1, df2], axis=1)
'''
	A	   B	C	  D	   A	 B	 C	 D
0	A0	B0	C0	D0	NaN	NaN	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN	NaN	NaN
4	NaN	NaN	NaN	NaN	A4	B4	C4	D4
5	NaN	NaN	NaN	NaN	A5	B5	C5	D5
6	NaN	NaN	NaN	NaN	A6	B6	C6	D6
7	NaN	NaN	NaN	NaN	A7	B7	C7	D7
'''

 

pd.concat( [df1, df2], axis=1)
# ==> 옆으로 붙이자 axis =1
#     옆으로는 or틱하게 열심히 확장 --> 늘어남
#     df1 컬럼의 수 + df2컬럼의 수 => 단순 나열
# ==> 지정하지 않은 반대방향: 가로 주 ㄹ인덱스를 통일하지 않으면
#                             이상하게 합쳐지게 된다
#     : df.rename(columns = {})
#       df.rename(index={~~~~})
# 합치기 전에 반듯이 체크를 하고 합쳐야 됨!!!

# 약간 섞어서 세팅!!!
# 살짝 겹쳐보겠습니다!!!
df1 = pd.DataFrame(
    {
        "A":["A0","A1","A2","A3"],
        "B":["B0","B1","B2","B3"],
        "C":["C0","C1","C2","C3"],
        "D":["D0","D1","D2","D3"]
    },
    index=[0,1,2,3]
)
df1

df2 = pd.DataFrame(
    {
        "A":["A4","A5","A6","A7"],
        "B":["B4","B5","B6","B7"],
        "CC":["C4","C5","C6","C7"],
        "DD":["D4","D5","D6","D7"]
    },
    index=[2,3,5,6]
)
df2
'''
	 A	 B	CC	DD
2	A4	B4	C4	D4
3	A5	B5	C5	D5
5	A6	B6	C6	D6
6	A7	B7	C7	D7

'''

pd.concat( [df1, df2], axis=0)
'''
	 A	B	   C	 D	CC	DD
0	A0	B0	C0	D0	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN
2	A4	B4	NaN	NaN	C4	D4
3	A5	B5	NaN	NaN	C5	D5
5	A6	B6	NaN	NaN	C6	D6
6	A7	B7	NaN	NaN	C7	D7

'''

 

정리

  • 내가 합치려고 하는 지정한 방향으로 그냥 다 (겹치건 말건 다 펼치자)
  • 지정하지 않은 반대 방향 : 공통되면 축약

** 원하지 않게 합쳐질 수 있음 !!!

temp = pd.concat( [df1, df2], axis=0)
temp
'''
	 A	 B	 C	 D	CC	DD
0	A0	B0	C0	D0	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN
2	A4	B4	NaN	NaN	C4	D4
3	A5	B5	NaN	NaN	C5	D5
5	A6	B6	NaN	NaN	C6	D6
6	A7	B7	NaN	NaN	C7	D7

'''

temp.loc[2, :] # --> 자료형 : DF
'''
	 A	 B	 C	 D	CC	DD
2	A2	B2	C2	D2	NaN	NaN
2	A4	B4	NaN	NaN	C4	D4

'''

temp.loc[5, :]  # --> 자료형 :Series
'''
	 5
A	 A6
B	 B6
C	 NaN
D	 NaN
CC	C6
DD	D6

dtype: object
'''

temp.reset_index()
'''
	index	A	B	C	D	CC	DD
0	   0	A0	B0	C0	D0	NaN	NaN
1	   1	A1	B1	C1	D1	NaN	NaN
2	   2	A2	B2	C2	D2	NaN	NaN
3	   3	A3	B3	C3	D3	NaN	NaN
4	   2	A4	B4	NaN	NaN	C4	D4
5	   3	A5	B5	NaN	NaN	C5	D5
6	   5	A6	B6	NaN	NaN	C6	D6
7	   6	A7	B7	NaN	NaN	C7	D7

'''

pd.concat( [df1, df2], axis=0, ignore_index=True)
'''
	 A	 B	 C	 D	CC	DD
0	A0	B0	C0	D0	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN
4	A4	B4	NaN	NaN	C4	D4
5	A5	B5	NaN	NaN	C5	D5
6	A6	B6	NaN	NaN	C6	D6
7	A7	B7	NaN	NaN	C7	D7

'''

pd.concat( [df1, df2], axis=1, ignore_index=True)
'''
	 0	 1	 2	 3	 4	 5	 6	 7
0	A0	B0	C0	D0	NaN	NaN	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN	NaN	NaN
2	A2	B2	C2	D2	A4	B4	C4	D4
3	A3	B3	C3	D3	A5	B5	C5	D5
5	NaN	NaN	NaN	NaN	A6	B6	C6	D6
6	NaN	NaN	NaN	NaN	A7	B7	C7	D7

'''

정리 ) ** 이거 제대로 안 하면 오류나

  • 기준이 되는 방향
    • 일단 다 붙이기(중복되건 말건 알바아님)
    • 반대 방향으로는 or틱하게 (겹치면 공유, 새로운 추가)
  • ⇒ 가로/세로 틀을 먼저 생성
  • ⇒ 나열한 DF에서 가지고 올 수 있는 정보가 있으면 가지고 오고, 못하면 NaN
pd.concat( [df1, df2], axis=1).reindex( df2.index)
# ==> 이런 스타일 : 합친 df 중에서 df2를 기준으로 봅시다
# sql : left/right join
'''
	 A	 B	 C	 D	 A	 B	CC	DD
2	A2	B2	C2	D2	A4	B4	C4	D4
3	A3	B3	C3	D3	A5	B5	C5	D5
5	NaN	NaN	NaN	NaN	A6	B6	C6	D6
6	NaN	NaN	NaN	NaN	A7	B7	C7	D7

'''

방법2) 단순하게 이어붙이는 것이 아니라 ⇒ 특정 조건에 맞는 것들만 네가 알아서 좀 가져다 붙여줘

  • sql 에서 join → pandas에서는 pd.merge()
baseball_player = pd.DataFrame(
    {
        "player_name" : ["이정후", "김광현","이대호","추신수","강민호"],
        "team_no"     : [ 1993 ,     2001,     2001, None,  2010]
    }
)
baseball_player
'''
	player_name	team_no
0	이정후	     1993.0
1	김광현	     2001.0
2	이대호	     2001.0
3	추신수	     NaN
4	강민호	     2010.0

'''

baseball_team = pd.DataFrame(
    {
        "team_name": ["키움", "국대", "삼성", "태평양"],
        "team_id"  : [1993, 2001, 2010, 3000],
        "team_home": ["고척", "잠실","대구","문학"]
    }
)
baseball_team
'''
	team_name	team_id	team_home
0	 키움	      1993	 고척
1	 국대	      2001	 잠실
2	 삼성	      2010	 대구
3	 태평양	    3000	 문학

'''
  • 선수와 그 선수 소속팀에 대한 정보 DF ⇒ 소속있는 현역 선수 + 지금 팀 은퇴한 선수
  • kbo 팀들에 대한 DF ⇒ 지금 등록된 팀 + 지금은 합병된 팀

 

#판다스에서 기준 on -> 세로 컬럼명, 가로 인덱스 
'''
pd.merge( L-DF, R-DF, how = "어떻게 " ,
         left_on = L_DF의 기준 컬럼명/들,
          right_on = R-DF의 기준 컬럼명/들 )
'''

#pandas 기준으로 왼쪽 : 선수, 오른쪽 : 팀 세팅
# ==> 분석을 선수 중심으로 하자
# 기준: 선수 정보 DF
# 합칠 기준 : 팀의 정보가 있으면 가지고 오고, 없으면 말자 ~~
#     연결고리: 선수 DF(team_no), 팀DF(tean_id)

pd.merge( baseball_player, baseball_team,
          how= "left",
          left_on = "team_no",
          right_on="team_id")
# ==> 혹시 양쪽 기준 컬럼명이 동일하면 on = "team_ids"
#                                      left_on ="team_id", right_on="team_id"
# left/right join주의사항!!!
# ==> 연결에 대한 매칭이 1:1, 1:n, n:m
#     데이터의 수가 달라질 수 있음!!!
'''
	player_name	team_no	team_name	team_id	team_home
0	  이정후	  1993.0	  키움	   1993.0	  고척
1	  김광현	  2001.0	  국대	   2001.0	  잠실
2	  이대호	  2001.0	  국대	   2001.0	  잠실
3	  추신수	   NaN	    NaN	      NaN	    NaN
4	  강민호	  2010.0	  삼성	   2010.0	  대구

'''

# 팀DF중심으로 --> 선수 정보 L, 팀 R
#  ==> 지금 현역으로 활동하는 선수정보가 있으면 가지고오고, 없으면 말자!!!
pd.merge( baseball_player, baseball_team,
          how= "right",
          left_on = "team_no",
          right_on="team_id")
'''
	player_name	team_no	team_name	team_id	team_home
0	 이정후	     1993.0	   키움	    1993	  고척
1	 김광현	     2001.0	   국대	    2001	  잠실
2	 이대호	     2001.0	   국대	    2001	  잠실
3	 강민호	     2010.0	   삼성	    2010	  대구
4	 NaN	        NaN	    태평양	  3000	  문학

'''

# 지금 현역으로 활동하는 선수의 정보와,
# 그 선수가 속한 팀의 정보만 보자 
# ==> 선수/팀 모두 있는 경우만 보여줘 : inner join
pd.merge( baseball_player, baseball_team,
          how= "inner",
          left_on = "team_no",
          right_on="team_id")
'''
	player_name	team_no	team_name	team_id	team_home
0	 이정후	     1993.0	   키움	    1993	  고척
1	 김광현	     2001.0	   국대	    2001	  잠실
2	 이대호	     2001.0	   국대	    2001	  잠실
3	 강민호	     2010.0	   삼성	    2010	  대구
'''

exclusive join : sql에서도 따로 명령어 없음 ⇒ where 사용해서 → where ~~ is null

  • pandas에서는 불리언 인덱스 is null(), notnull()
# --> 선수들에 대한 정보들에서 혹시 작성하다가 팀에서 누락된 것인지
#                                   은퇴해서 없는 것인지 체크 

pd.merge( baseball_player, baseball_team,
          how= "left",
          left_on = "team_no",
          right_on="team_id")
'''
	player_name	team_no	team_name	team_id	team_home
0	  이정후	  1993.0	  키움	   1993.0	  고척
1	  김광현	  2001.0	  국대	   2001.0	  잠실
2	  이대호	  2001.0	  국대	   2001.0	  잠실
3	  추신수	   NaN	    NaN	      NaN	    NaN
4	  강민호	  2010.0	  삼성	   2010.0	  대구

'''

temp[ temp.loc[:,"team_id"].isnull()]
'''
	player_name	team_no	team_name	team_id	team_home
5	   추신수	    NaN	       NaN	  NaN	     NaN

'''

temp.loc[ temp.loc[:,"team_id"].isnull(),:]
'''
	player_name	team_no	team_name	team_id	team_home
5	   추신수	    NaN	       NaN	  NaN	     NaN

'''

혹시 내가 2개 (선수, 팀) 정보를 합치려고 하는데,,, 안 합쳐지는 친구들이 있는지 체크 좀 해보자!!! ⇒ 뭐라도 하나 누락된 데이터들을 보자!!! : 실수 or 찐!!

  • step1) 일단 다 합쳐보자 : full join ---> how : outer
  • step2) 양쪽에 대해서 다 누락을 체크!!!
temp = pd.merge( baseball_player, baseball_team,
          how= "outer",
          left_on = "team_no",
          right_on="team_id")
temp
'''
	player_name	team_no	team_name	team_id	team_home
0	   이정후	   1993.0	  키움	   1993.0	  고척
1	   김광현	   2001.0	  국대	   2001.0	  잠실
2	   이대호	   2001.0	  국대	   2001.0	  잠실
3	   강민호	   2010.0	  삼성	   2010.0	  대구
4	     NaN	   NaN	   태평양	   3000.0	  문학
5	   추신수	   NaN	    NaN	       NaN	  NaN

'''

temp[ (temp.loc[:,"team_no"].isnull()) |
        (temp.loc[:,"team_id"].isnull()) ]
'''
	player_name	team_no	team_name	team_id	team_home
4	    NaN	       NaN	 태평양	   3000.0	  문학
5	   추신수	     NaN	   NaN	     NaN	   NaN

'''

⇒ 위의 경우는 2개 DF 모두 연결 기준 컬럼에 존재할 때

+++ 1개는 컬럼에 존재, 1개는 가로줄 인덱스에 존재

baseball_player = pd.DataFrame(
    {
        "player_name" : ["이정후", "김광현","이대호","추신수","강민호"],
        "team_no"     : [ 1993 ,     2001,     2001, None,  2010]
    },
    index = ["p_01","p_02","p_03","p_04","p_05"]
)
baseball_player.index.name="player_id" # -->인덱스 이름!!
baseball_player
'''
	         player_name	team_no
player_id		
p_01	       이정후	     1993.0
p_02	       김광현	     2001.0
p_03	       이대호	     2001.0
p_04	       추신수	      NaN
p_05	       강민호	     2010.0

'''

baseball_team = pd.DataFrame(
    {
        "team_name": ["키움", "국대", "삼성", "태평양"],
        "team_home": ["고척", "잠실","대구","문학"]
    },
    index = [1993, 2001, 2010, 3000]
)
baseball_team
'''
	   team_name	team_home
1993	    키움	고척
2001	    국대	잠실
2010	    삼성	대구
3000	   태평양	문학

'''

선수 중심으로, 팀에 대한 정보가 있으면 붙여서 보자

  • 선수 : L , 팀 : R
  • ⇒ 연결 기준 : 팀 고유값
    • 선수DF ---> 컬럼 --> left_on ="team_no”
    • 팀 DF ---> 가로인덱스 --> right_index = T/F

참고) 양쪽 DF의 index를 기준으로 할래요 : index=True

pd.merge( baseball_player, baseball_team,
          how= "left",
          left_on = "team_no",
          right_index=True)
'''
	         player_name	team_no	team_name	team_home
player_id				
p_01	           이정후	  1993.0	 키움	    고척
p_02	           김광현	  2001.0	 국대	    잠실
p_03	           이대호	  2001.0	 국대	    잠실
p_04	           추신수	   NaN	    NaN	     NaN
p_05	           강민호	  2010.0	  삼성	  대구

'''

*** 자주 사용되는 방법들이다~

'데이터분석 > Pandas' 카테고리의 다른 글

Selenium 02 _ dart_selenium  (0) 2025.08.22
Selenium 01 _ selenium 설치 및 실행  (0) 2025.08.22
[Python] Pandas 10 _ csv  (0) 2025.08.21
[Python] Pandas 09 _ daum_site  (2) 2025.08.21
[Python] Pandas 08 _ dart_site  (5) 2025.08.21