[Pandas]내가 보려고 올린 Pandas 정리5

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!


Pandas merge, join, concat

  • 판다스 사이트
  • 두 개 이상의 데이터프레임을 병합해주는 병합(merge)이나 연결(concate)이 있다.
  • merge(), join(), concat()
# 모듈 설치
import pandas as pd
import numpy as np
import random
# output에 여러가지 결과가 나올 수 있도록 한다.
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity="all"

1. 데이터 병합

1) merge()

  • 두 데이터 프레임의 공통 열(column)이나 인덱스(index)를 기준으로 합침
  • key : 기준이 되는 열

사용방식

  • df.merge(df1) : 두 df를 병합시킴
  • 기본은 inner join : 양쪽에 동일하게 존재하는 키만 표시
  • key : 기준열
    • 실제 데이터 필드거나 행 인덱스 일 수 있다.
  • 병합방식
    • inner join : 양쪽 데이터프레임에서 모두 키가 존재하는 데이터만 표시
    • outer join : 한쪽에만 키가 존재하면 데이터를 표시
    • 병합방식(매개변수 how) : how=inner(default), how=outer

예제1

  • 축구 선수의 정보를 담고 있는 데이터 프레임
df1 = pd.DataFrame({'선수번호':[1,2,3,4,5,6,7], 
                   '이름':['이운재','박지성','손흥민','차범근','김남일','홍명보','김민재']},
                   columns = ['선수번호','이름'])
df1
선수번호 이름
0 1 이운재
1 2 박지성
2 3 손흥민
3 4 차범근
4 5 김남일
5 6 홍명보
6 7 김민재
  • 선수 연봉 정보 데이터 프레임
# 예제 df 생성 - 예금 정보 df
df2 = pd.DataFrame({'선수번호':[1, 1, 5, 6, 8, 1], 
                   '연봉(억)':[10, 20, 30, 40, 200, 5]},
                   columns = ['선수번호','연봉(억)'])
df2
선수번호 연봉(억)
0 1 10
1 1 20
2 5 30
3 6 40
4 8 200
5 1 5

merge 명령으로 두 데이터프레임을 병합하는 문법

  • merge(df1, df2, how, on, left_on, right_on, left_index, right_index)

  • 모든 인수 생략(병합 df를 제외한) 공통 이름을 갖고 있는 열
  • ‘고객번호’가 키가 됨
  • 양쪽에 모두 존재하는 키의 data만 보여주는 inner join 방식을 사용
    • pandas.merge(df1, df2)
    • df1.merge(df2)
df1.head(1)
df2.tail(1)
선수번호 이름
0 1 이운재
선수번호 연봉(억)
5 1 5

df1.merge(df2)

  • 기준 데이터프레임은 df1
df1.merge(df2)
선수번호 이름 연봉(억)
0 1 이운재 10
1 1 이운재 20
2 1 이운재 5
3 5 김남일 30
4 6 홍명보 40

pd.merge(데이터프레임1, 데이터프레임2)

  • 기준이 되는 DF는 왼쪽에 위치한다.
# 왼쪽에 기준 데이터 프레임(df1)
pd.merge(df1,df2)
선수번호 이름 연봉(억)
0 1 이운재 10
1 1 이운재 20
2 1 이운재 5
3 5 김남일 30
4 6 홍명보 40

how = ‘인수’

merge( , how = ‘outer’)

  • how = inner/outer/left/right
    • how=left : 왼쪽 df에 있는 모든 키의 데이터는 표시
    • how=right : 오른쪽 df 에 있는 모든 키의 데이터는 표시
  • outer join
    • 키 값이 한쪽에만 있어도 모든 데이터를 보여준다.
    • 다른 데이터프레임에 데이터가 존재하지 않으면 NaN으로 표시됨
pd.merge(df1, df2, how='outer')
선수번호 이름 연봉(억)
0 1 이운재 10.0
1 1 이운재 20.0
2 1 이운재 5.0
3 2 박지성 NaN
4 3 손흥민 NaN
5 4 차범근 NaN
6 5 김남일 30.0
7 6 홍명보 40.0
8 7 김민재 NaN
9 8 NaN 200.0
  • left join
pd.merge(df1, df2, how='left')
선수번호 이름 연봉(억)
0 1 이운재 10.0
1 1 이운재 20.0
2 1 이운재 5.0
3 2 박지성 NaN
4 3 손흥민 NaN
5 4 차범근 NaN
6 5 김남일 30.0
7 6 홍명보 40.0
8 7 김민재 NaN
  • right join
pd.merge(df1, df2, how='right')
선수번호 이름 연봉(억)
0 1 이운재 10
1 1 이운재 20
2 1 이운재 5
3 5 김남일 30
4 6 홍명보 40
5 8 NaN 200

동일한 키 값이 있는 경우

  • 키값이 같은 데이터가 여러개 있는 경우에는 있을 수 있는 모든 경우의 수를 따져서 조합을 만들어 낸다.

예제2. 데이터프레임 생성

  • 데이터프레임1
# 예제 df 생성 
# 열: 신발종류, 사이즈
df1 = pd.DataFrame({
    '신발종류':['nike','nike','adidas','adidas'],
    '사이즈':[240, 230, 250, 230]},
    columns=['신발종류','사이즈'])
df1
신발종류 사이즈
0 nike 240
1 nike 230
2 adidas 250
3 adidas 230
  • 데이터프레임2
# 열 : 신발종류, 가격(만원)
df2 = pd.DataFrame({
    '신발종류': ['nike','adidas','adidas','puma'],
    '가격(만원)':[7,5,6,6]},
    columns=['신발종류','가격(만원)'])
df2
신발종류 가격(만원)
0 nike 7
1 adidas 5
2 adidas 6
3 puma 6
#양쪽 데이터프레임에서 공통된 키만 표현

df1.head(1)
df2.head(1)
pd.merge(df1,df2)
pd.merge(df1,df2, how='left')
pd.merge(df1,df2, how='right')
pd.merge(df1,df2, how='outer')
신발종류 사이즈
0 nike 240
신발종류 가격(만원)
0 nike 7
신발종류 사이즈 가격(만원)
0 nike 240 7
1 nike 230 7
2 adidas 250 5
3 adidas 250 6
4 adidas 230 5
5 adidas 230 6
신발종류 사이즈 가격(만원)
0 nike 240 7
1 nike 230 7
2 adidas 250 5
3 adidas 250 6
4 adidas 230 5
5 adidas 230 6
신발종류 사이즈 가격(만원)
0 nike 240.0 7
1 nike 230.0 7
2 adidas 250.0 5
3 adidas 230.0 5
4 adidas 250.0 6
5 adidas 230.0 6
6 puma NaN 6
신발종류 사이즈 가격(만원)
0 nike 240.0 7
1 nike 230.0 7
2 adidas 250.0 5
3 adidas 250.0 6
4 adidas 230.0 5
5 adidas 230.0 6
6 puma NaN 6

merge()의 on 인수를 사용하여 기준열 설정을 통한 병합

key

  • 두 데이터 프레임에서 이름이 같은 열은 모두 키가 될 수 있다.
  • 열이름이 같아도 키로 사용할 수 없는 열이 있으면 on 인수로 기준열을 명시해야 한다.

예제3.

# 예제 df
df1 = pd.DataFrame({
    '고객명':['동준','동준','풍호'],
    '날짜' : ['2022-01-14','2022-01-15','2021-01-14'],
    '데이터':[1000, 2000, 30000]
})
df1
고객명 날짜 데이터
0 동준 2022-01-14 1000
1 동준 2022-01-15 2000
2 풍호 2021-01-14 30000
df2 = pd.DataFrame({
    '고객명':['동준','풍호'],
    '데이터':['여자','남자']
})
df2
고객명 데이터
0 동준 여자
1 풍호 남자

기준열을 직접 지정 : on=기준열 이름

  • 반환 결과에 동일 필드명이 있을 경우에는 필드명_x, 필드명_y로 필드명을 변경해서 표현
pd.merge(df1, df2, on='고객명')
고객명 날짜 데이터_x 데이터_y
0 동준 2022-01-14 1000 여자
1 동준 2022-01-15 2000 여자
2 풍호 2021-01-14 30000 남자

키가 되는 기준열 이름이 두 데이터 프레임에서 다르게 나타나는 경우

  • left_on, right_on 인수를 사용해서 기준열을 명시해야 함

예제4.

df1=pd.DataFrame({
    '이름' :['동준','굿전','굿전'],
    '성적' :[100,90,80]
})
df2 = pd.DataFrame({
    '성명' :['동준','동준','굿전'],
    '성적2':[95,85,90]
})
df1.head(1)
df2.head(1)
이름 성적
0 동준 100
성명 성적2
0 동준 95
pd.merge(df1, df2, left_on='이름', right_on='성명')
# 양쪽에서 기준이되는 열의 이름이 다르기 때문에 on인수를 두번사용
# 출력결과는 양쪽 필드 명이 다르기 때문에 기준열이 모두나타난다.
이름 성적 성명 성적2
0 동준 100 동준 95
1 동준 100 동준 85
2 굿전 90 굿전 90
3 굿전 80 굿전 90

인덱스 기준으로 병합

: 일반 데이터 열이 아닌 인덱스를 기준으로 merge 할수도 있음

  • 인덱스를 기준열로 사용하려면
    • left_index = True 또는
    • right_index = True 설정을 하게 됨

예제5. 데이터프레임의 인덱스를 기준열로 사용하는 경우

df1 = pd.DataFrame({
    '도시': ['서울','서울','서울','부산','부산'],
    '연도': [2000, 2005, 2010, 2000, 2005],
    '인구': [9853972, 9762546, 9631482, 3655437, 3512547]    
})

df2=pd.DataFrame(
    np.arange(12).reshape((6,2)),
    index=[['부산','부산','서울','서울','서울','서울'],
          [2000, 2005, 2000, 2005, 2010, 2015]],
    columns=['데이터1','데이터2']
)

df1
df2
도시 연도 인구
0 서울 2000 9853972
1 서울 2005 9762546
2 서울 2010 9631482
3 부산 2000 3655437
4 부산 2005 3512547
데이터1 데이터2
부산 2000 0 1
2005 2 3
서울 2000 4 5
2005 6 7
2010 8 9
2015 10 11
pd.merge(df1, df2, left_on=['도시','연도'], right_index = True)
도시 연도 인구 데이터1 데이터2
0 서울 2000 9853972 4 5
1 서울 2005 9762546 6 7
2 서울 2010 9631482 8 9
3 부산 2000 3655437 0 1
4 부산 2005 3512547 2 3

예제6. 두 데이터프레임의 key가 모두 인덱스인 경우

df1 = pd.DataFrame([[1.,2.],[3.,4.],[5.,6.]],
                   index=['a','c','e'],
                   columns=['서울','부산'])
df1

df2=pd.DataFrame([[7.,8.],[9.,10.],
                  [11.,12.],[13.,14.]],
                 index=['b','c','d','e'],
                 columns=['대구','광주'])
df2
서울 부산
a 1.0 2.0
c 3.0 4.0
e 5.0 6.0
대구 광주
b 7.0 8.0
c 9.0 10.0
d 11.0 12.0
e 13.0 14.0

두 데이터프레임의 인덱스가 키로 사용될 경우

# 두 데이터프레임의 key가 모두 인덱스인 경우
pd.merge(df1, df2, how='outer', left_index=True, right_index=True)
서울 부산 대구 광주
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0

2) join() - 행방향

  • Dataframe1.join(Dataframe2. how=’left/right/inner/outer’, on=keys)

  • 사용 방법은 merge()와 동일하며, 행 인덱스를 기준으로 병합
  • Dataframe1.join(Dataframe2. how=’left’)가 default값
df1.join(df2, how = 'outer')
서울 부산 대구 광주
a 1.0 2.0 NaN NaN
b NaN NaN 7.0 8.0
c 3.0 4.0 9.0 10.0
d NaN NaN 11.0 12.0
e 5.0 6.0 13.0 14.0

2. 데이터 연결

concat()

pd.concat([left, right], axis=0, join=’outer’, ignore_index=False, keys=None)

  • left, right : Series, DataFrame, Panel object 리스트
  • axis : 0은 위+아래로 합치기, 1은 왼쪽+오른쪽으로 합치기
  • join : ‘outer’: 합집합(union), ‘inner’: 교집합(intersection)
  • ignore_index : False: 기존 index 유지, True: 기존 index 무시
  • keys : 계층적 index 사용하려면 keys 튜플 입력

  • 기준열 없이 데이터를 합친다
  • 위 아래로 데이터를 결합하는 행 결합(row bind)이 기본
  • axis 속성을 1로 설정하면 열 결합(column bind)을 수행
  • 단순히 두 시리즈나 데이터프레임을 연결하기 때문에 인덱스 값이 중복될 수 있다.

행결합 : pd.concat([df1,df2], axis=0)

열결합 : pd.concat([df1,df2],axis=1)

두 시리즈 데이터 연결

예제1.

  • 두 시리즈 데이터 생성
s1 = pd.Series([0,1], index = ['A','B'])
s1
s2 = pd.Series([2,3,4], index = ['A','B','C'])
s2
A    0
B    1
dtype: int64






A    2
B    3
C    4
dtype: int64
  • 두 시리즈 데이터 연결
# 두 시리즈 연결 : 행방향으로 합침 (axis=0)
pd.concat([s1,s2])
A    0
B    1
A    2
B    3
C    4
dtype: int64
# 두 시리즈 연결 : 열방향으로 합침
pd.concat([s1,s2], axis=1)
0 1
A 0.0 2
B 1.0 3
C NaN 4

두 데이터프레임 연결

예제2.

  • 데이터프레임 생성
# concat 연결
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])

df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'E': ['C4', 'C5', 'C6', 'C7'],
                    'F': ['D4', 'D5', 'D6', 'D7']},
                   index=[0, 1, 2, 3])

df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                    'B': ['B8', 'B9', 'B10', 'B11'],
                    'C': ['C8', 'C9', 'C10', 'C11'],
                    'D': ['D8', 'D9', 'D10', 'D11']},
                   index=[1,2,3,4])
df1
df2
df3
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
A B E F
0 A4 B4 C4 D4
1 A5 B5 C5 D5
2 A6 B6 C6 D6
3 A7 B7 C7 D7
A B C D
1 A8 B8 C8 D8
2 A9 B9 C9 D9
3 A10 B10 C10 D10
4 A11 B11 C11 D11

데이터 프레임 행 결합

  • 행을 모두 표현
  • join 인수 생략 : 기본값이 ‘outer’로 지정되어 있음 (모든 열 표현)
result = pd.concat([df1,df2])
result
A B C D E F
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
0 A4 B4 NaN NaN C4 D4
1 A5 B5 NaN NaN C5 D5
2 A6 B6 NaN NaN C6 D6
3 A7 B7 NaN NaN C7 D7
pd.concat([df1,df2], join = 'outer') # 위 코드와 결과가 같음
A B C D E F
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
0 A4 B4 NaN NaN C4 D4
1 A5 B5 NaN NaN C5 D5
2 A6 B6 NaN NaN C6 D6
3 A7 B7 NaN NaN C7 D7

인덱스가 중복된 경우 : 인덱싱을 수행하면?

# 인덱스가 중복 된 경우 인덱싱을 수행 하면 ?
result
result.iloc[0] # index가 0번째 위치에 있는 행 시리즈 반환
result.loc[0] # index가 0인 행들 전부 반환
A B C D E F
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
0 A4 B4 NaN NaN C4 D4
1 A5 B5 NaN NaN C5 D5
2 A6 B6 NaN NaN C6 D6
3 A7 B7 NaN NaN C7 D7
A     A0
B     B0
C     C0
D     D0
E    NaN
F    NaN
Name: 0, dtype: object
A B C D E F
0 A0 B0 C0 D0 NaN NaN
0 A4 B4 NaN NaN C4 D4

인덱스가 중복되므로 기본 인덱스로 재설정

  • 인덱스 열 제거 : drop=True
# 인덱스가 중복 되므로 기본 인덱스로 재 설정
# 인덱스 열은 제거

result.reset_index(drop=True)
A B C D E F
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
concat( , join = ‘inner’)

공통된 열만 표현

# concat() : 행결합 - 행은 모두 표현
# join='inner' 이므로 열은 공통열만 표현

pd.concat([df1,df2], join = 'inner')
# df1, df2가 가진 공통열 A, B를 가져옴
A B
0 A0 B0
1 A1 B1
2 A2 B2
3 A3 B3
0 A4 B4
1 A5 B5
2 A6 B6
3 A7 B7
concat( , ignore_index = True)

기존 인덱스 제거 후 제로베이스 인덱스 설정

# ignore_index = True : 기존 인덱스 제거 후 제로베이스 인덱스 설정

pd.concat([df1,df2], join = 'inner', ignore_index = True)
A B
0 A0 B0
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4
5 A5 B5
6 A6 B6
7 A7 B7
concat( , keys=[])

상위 레벨 인덱스 설정

# keys 파라미터를 통해 상위레벨 인덱스 설정 가능
# 3개의 df이므로 각 df에 대응되는 상위 레벨 인덱스를 정의
dF1 = pd.concat([df1,df2,df3], keys=['df1','df2','df3'])
dF1
A B C D E F
df1 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
df2 0 A4 B4 NaN NaN C4 D4
1 A5 B5 NaN NaN C5 D5
2 A6 B6 NaN NaN C6 D6
3 A7 B7 NaN NaN C7 D7
df3 1 A8 B8 C8 D8 NaN NaN
2 A9 B9 C9 D9 NaN NaN
3 A10 B10 C10 D10 NaN NaN
4 A11 B11 C11 D11 NaN NaN
  • 다중 인덱스인 경우 데이터 접근 : .연산자를 이용한 체인 인덱싱
# 다중 인덱싱 : . 연산자를 이용한 접근
dF1.loc['df3'].loc[1:4]
A B C D E F
1 A8 B8 C8 D8 NaN NaN
2 A9 B9 C9 D9 NaN NaN
3 A10 B10 C10 D10 NaN NaN
4 A11 B11 C11 D11 NaN NaN

concat() 를 이용한 열 결합

pd.concat([df1,df2], axis=1, join=’inner/outer’)

  • axis=1
    • 데이터프레임들의 열을 결합
  • join=’outer’ : 기본 설정
    • 모든 행을 표시하고 해당 행의 데이터가 없는 열의 원소는 NaN으로 표시
  • join=’inner’
    • 병합하는 데이터프레임에 중복되는 인덱스의 행만 표시

예제3.

# 예제 df 생성
df1=pd.DataFrame(
    np.arange(6).reshape(3,2),
    index=['a','b','c'],
    columns=['데이터1','데이터2']
)
df1

df2=pd.DataFrame(
    5+np.arange(4).reshape(2,2),
    index=['a','c'],
    columns=['데이터2','데이터4']
)
df2
데이터1 데이터2
a 0 1
b 2 3
c 4 5
데이터2 데이터4
a 5 6
c 7 8
  • concat( , axis=1, )을 이용한 열 결합 : outer join이 기본으로 적용
pd.concat([df1,df2], axis=1)
# join ='outer'가 기본이므로 생략 가능
데이터1 데이터2 데이터2 데이터4
a 0 1 5.0 6.0
b 2 3 NaN NaN
c 4 5 7.0 8.0
  • concat( , axis=0, )을 이용한 행 결합
# 행 결합
pd.concat([df1,df2])
데이터1 데이터2 데이터4
a 0.0 1 NaN
b 2.0 3 NaN
c 4.0 5 NaN
a NaN 5 6.0
c NaN 7 8.0
  • inner join이 적용된 열 결합
pd.concat([df1,df2], axis=1, join='inner')
데이터1 데이터2 데이터2 데이터4
a 0 1 5 6
c 4 5 7 8

2022

[web]jQuery 복습 3

2 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]jQuery 복습 2

11 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]jQuery 복습 1

16 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리4

6 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리3

6 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리2

6 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리1

7 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]CSS 기초 정리

9 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]HTML 기초 정리

2 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[Pandas]pandas 연습

3 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

맨 위로 이동 ↑

2021

[Python기초]module

1 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

맨 위로 이동 ↑