판다 병합 101

Dec 06 2018
  • 팬더 로 ( INNER| ( LEFT| RIGHT| FULL) OUTER) 를 수행하는 방법은 JOIN무엇입니까?
  • 병합 후 누락 된 행에 대한 NaN을 추가하려면 어떻게합니까?
  • 병합 후 NaN을 제거하려면 어떻게합니까?
  • 인덱스에 병합 할 수 있습니까?
  • 팬더와 교차 결합 하시겠습니까?
  • 여러 DataFrame을 어떻게 병합합니까?
  • merge? join? concat? update? WHO? 뭐? 왜?!

... 그리고 더. pandas 병합 기능의 다양한 측면에 대해 묻는 이러한 반복되는 질문을 보았습니다. 오늘날 병합 및 다양한 사용 사례와 관련된 대부분의 정보는 단어가 잘못되고 검색 할 수없는 수십 개의 게시물에 조각화되어 있습니다. 여기서의 목표는 후세에 대한 더 중요한 몇 가지 사항을 수집하는 것입니다.

이 글 상품 문의 글이 일반적인 팬더 관용구에 도움이 사용자 가이드 시리즈의 다음 분할 될 운명이된다 ( 회전이 게시물에 , 및 연결에이 게시물 나중에 내가에 접촉 될 것이다).

이 게시물은 문서를 대체하기위한 것이 아니므 로이 게시물도 읽어보십시오! 여기에서 일부 예제를 가져 왔습니다.

답변

696 cs95 Dec 06 2018 at 13:41

이 게시물은 독자들에게 pandas와 SQL 방식의 병합, 사용 방법 및 사용하지 않는 경우에 대한 입문서를 제공하는 것을 목표로합니다.

특히,이 게시물의 내용은 다음과 같습니다.

  • 기본-조인 유형 (LEFT, RIGHT, OUTER, INNER)

    • 다른 열 이름으로 병합
    • 출력에서 중복 병합 키 열 방지
  • 다른 조건에서 인덱스와 병합

    • 명명 된 인덱스를 효과적으로 사용
    • 하나의 인덱스와 다른 컬럼의 병합 키
  • 열 및 인덱스에 대한 다중 병합 (고유 및 비 고유)

  • merge및에 대한 주목할만한 대안join

이 게시물이 거치지 않는 내용 :

  • 성능 관련 토론 및 타이밍 (현재). 적절한 경우 더 나은 대안에 대한 가장 주목할만한 언급.
  • 접미사 처리, 추가 열 제거, 출력 이름 변경 및 기타 특정 사용 사례. 그것을 다루는 다른 (읽기 : 더 나은) 게시물이 있습니다.

참고
대부분의 예제는 달리 지정하지 않는 한 다양한 기능을 보여 주면서 INNER JOIN 연산으로 기본 설정됩니다.

또한 여기에있는 모든 DataFrame을 복사 및 복제 할 수 있으므로 함께 재생할 수 있습니다. 또한 클립 보드에서 DataFrames를 읽는 방법에 대한 이 게시물 을 참조하십시오 .

마지막으로 JOIN 작업의 모든 시각적 표현은 Google 드로잉을 사용하여 손으로 그린 ​​것입니다. 여기 에서 영감 .

충분한 토크, 사용 방법을 보여주세요 merge!

설정

np.random.seed(0)
left = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'value': np.random.randn(4)})    
right = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'value': np.random.randn(4)})
  
left

  key     value
0   A  1.764052
1   B  0.400157
2   C  0.978738
3   D  2.240893

right

  key     value
0   B  1.867558
1   D -0.977278
2   E  0.950088
3   F -0.151357

간단하게하기 위해 키 열의 이름은 현재 동일합니다.

INNER는 JOIN 에 의해 표현된다

참고
향후의 수치는이 모든 규칙을 따라야와 함께,이를 :

  • 파란색 은 병합 결과에있는 행을 나타냅니다.
  • 빨간색 은 결과에서 제외 된 행 (즉, 제거됨)을 나타냅니다.
  • 녹색NaN결과에서 s 로 대체 된 결 측값을 나타냅니다.

INNER JOIN을 수행하려면 merge왼쪽 DataFrame 에서 호출 하여 오른쪽 DataFrame과 최소한 조인 키를 인수로 지정합니다.

left.merge(right, on='key')
# Or, if you want to be explicit
# left.merge(right, on='key', how='inner')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278

이 수익률 만 행 leftright공통 (이 예에서는, "B"와 "D) 키를 공유 할 수 있습니다.

LEFT OUTER는 가입 또는 왼쪽으로 표시 조인

를 지정하여 수행 할 수 있습니다 how='left'.

left.merge(right, on='key', how='left')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278

여기에서 NaN의 배치를주의 깊게 확인하십시오. 를 지정하면의 how='left'키만 left사용되며 누락 된 데이터 right는 NaN으로 대체됩니다.

그리고 마찬가지로 RIGHT OUTER JOIN 또는 RIGHT JOIN의 경우 ...

... 지정 how='right':

left.merge(right, on='key', how='right')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278
2   E       NaN  0.950088
3   F       NaN -0.151357

여기에서는의 키 right가 사용되고 누락 된 데이터 left가 NaN으로 대체됩니다.

마지막으로 FULL OUTER JOIN의 경우

지정하십시오 how='outer'.

left.merge(right, on='key', how='outer')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278
4   E       NaN  0.950088
5   F       NaN -0.151357

이것은 두 프레임의 키를 사용하며 두 프레임 모두에서 누락 된 행에 대해 NaN이 삽입됩니다.

문서는 이러한 다양한 병합을 멋지게 요약합니다.

기타 JOIN-LEFT-Excluding, RIGHT-Excluding 및 FULL-Excluding / ANTI JOINs

두 단계에서 LEFT-Excluding JOINRIGHT-Excluding JOIN 이 필요한 경우 .

LEFT-Excluding JOIN의 경우 다음과 같이 표시됩니다.

LEFT OUTER JOIN을 수행 한 다음 다음에서 오는 행만 필터링 (제외!)하여 시작 left합니다.

(left.merge(right, on='key', how='left', indicator=True)
     .query('_merge == "left_only"')
     .drop('_merge', 1))

  key   value_x  value_y
0   A  1.764052      NaN
2   C  0.978738      NaN

어디,

left.merge(right, on='key', how='left', indicator=True)

  key   value_x   value_y     _merge
0   A  1.764052       NaN  left_only
1   B  0.400157  1.867558       both
2   C  0.978738       NaN  left_only
3   D  2.240893 -0.977278       both

마찬가지로 RIGHT-Excluding JOIN의 경우

(left.merge(right, on='key', how='right', indicator=True)
     .query('_merge == "right_only"')
     .drop('_merge', 1))

  key  value_x   value_y
2   E      NaN  0.950088
3   F      NaN -0.151357

마지막으로 왼쪽 또는 오른쪽의 키만 유지하고 둘다는 유지하지 않는 병합을 수행해야하는 경우 (IOW, ANTI-JOIN 수행 ),

비슷한 방식으로 할 수 있습니다.

(left.merge(right, on='key', how='outer', indicator=True)
     .query('_merge != "both"')
     .drop('_merge', 1))

  key   value_x   value_y
0   A  1.764052       NaN
2   C  0.978738       NaN
4   E       NaN  0.950088
5   F       NaN -0.151357

키 열의 다른 이름

키 열의 이름이 다르게 지정되면 (예 : lefthas keyLeft, righthas keyRight대신 key) 다음 대신 left_onright_onas 인수 를 지정해야합니다 on.

left2 = left.rename({'key':'keyLeft'}, axis=1)
right2 = right.rename({'key':'keyRight'}, axis=1)

left2
 
  keyLeft     value
0       A  1.764052
1       B  0.400157
2       C  0.978738
3       D  2.240893

right2

  keyRight     value
0        B  1.867558
1        D -0.977278
2        E  0.950088
3        F -0.151357
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')

  keyLeft   value_x keyRight   value_y
0       B  0.400157        B  1.867558
1       D  2.240893        D -0.977278

출력에서 중복 키 열 방지

keyLeftfrom leftkeyRightfrom에서 병합 할 때 출력에 또는 right둘 중 하나만 원하는 경우 (둘 다 아님) 인덱스를 예비 단계로 설정하여 시작할 수 있습니다.keyLeftkeyRight

left3 = left2.set_index('keyLeft')
left3.merge(right2, left_index=True, right_on='keyRight')
    
    value_x keyRight   value_y
0  0.400157        B  1.867558
1  2.240893        D -0.977278

이것을 직전의 명령 출력 (즉,의 출력 left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner'))과 비교하면 keyLeft누락 된 것을 알 수 있습니다. 어떤 프레임의 인덱스가 키로 설정되어 있는지에 따라 유지할 열을 파악할 수 있습니다. 이는 예를 들어 일부 OUTER JOIN 작업을 수행 할 때 중요 할 수 있습니다.

다음 중 하나에서 단일 열만 병합 DataFrames

예를 들어

right3 = right.assign(newcol=np.arange(len(right)))
right3
  key     value  newcol
0   B  1.867558       0
1   D -0.977278       1
2   E  0.950088       2
3   F -0.151357       3

다른 열없이 "new_val"만 병합해야하는 경우 일반적으로 병합하기 전에 열의 하위 집합 만 사용할 수 있습니다.

left.merge(right3[['key', 'newcol']], on='key')

  key     value  newcol
0   B  0.400157       0
1   D  2.240893       1

LEFT OUTER JOIN을 수행하는 경우 더 성능이 좋은 솔루션에는 map다음 이 포함됩니다 .

# left['newcol'] = left['key'].map(right3.set_index('key')['newcol']))
left.assign(newcol=left['key'].map(right3.set_index('key')['newcol']))

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0

언급했듯이 이것은 유사하지만

left.merge(right3[['key', 'newcol']], on='key', how='left')

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0

여러 열에서 병합

둘 이상의 열에 결합하려면 목록을 지정하십시오 on(또는 left_onright_on).

left.merge(right, on=['key1', 'key2'] ...)

또는 이름이 다른 경우

left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])

기타 유용한 merge*작동 및 기능

이 섹션은 기본 사항 만 다루며 식욕을 돋우도록 설계되었습니다. 더 많은 예제와 사례를 들어, 참조 에 대한 문서를 merge, join그리고concat 뿐만 아니라 기능 사양에 대한 링크로.


인덱스 기반 * -JOIN (+ 인덱스-열 merges)

설정

np.random.seed([3, 14])
left = pd.DataFrame({'value': np.random.randn(4)}, index=['A', 'B', 'C', 'D'])    
right = pd.DataFrame({'value': np.random.randn(4)}, index=['B', 'D', 'E', 'F'])
left.index.name = right.index.name = 'idxkey'

left
           value
idxkey          
A      -0.602923
B      -0.402655
C       0.302329
D      -0.524349

right
 
           value
idxkey          
B       0.543843
D       0.013135
E      -0.326498
F       1.385076

일반적으로 인덱스 병합은 다음과 같습니다.

left.merge(right, left_index=True, right_index=True)


         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

인덱스 이름 지원

색인의 이름은 경우 v0.23 사용자는로 레벨 이름을 지정할 수 있습니다 on(또는 left_onright_on필요에 따라)를.

left.merge(right, on='idxkey')

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

하나의 인덱스, 다른 열의 병합

병합을 수행하기 위해 하나의 인덱스와 다른 컬럼의 인덱스를 사용하는 것이 가능합니다 (매우 간단합니다). 예를 들면

left.merge(right, left_on='key1', right_index=True)

또는 그 반대의 경우 ( right_on=...left_index=True).

right2 = right.reset_index().rename({'idxkey' : 'colkey'}, axis=1)
right2
 
  colkey     value
0      B  0.543843
1      D  0.013135
2      E -0.326498
3      F  1.385076

left.merge(right2, left_index=True, right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135

이 특별한 경우에 대한 색인의 left이름이 지정되므로 다음과 left_on같이 색인 이름을와 함께 사용할 수도 있습니다 .

left.merge(right2, left_on='idxkey', right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135

DataFrame.join
이 외에도 또 다른 간결한 옵션이 있습니다. DataFrame.join색인에서 조인하는 데 기본값을 사용할 수 있습니다 . DataFrame.join기본적으로 LEFT OUTER JOIN을 수행하므로 how='inner'여기에서 필요합니다.

left.join(right, how='inner', lsuffix='_x', rsuffix='_y')

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

그렇지 않으면 오류가 발생 하므로 lsuffixrsuffix인수 를 지정해야합니다 join.

left.join(right)
ValueError: columns overlap but no suffix specified: Index(['value'], dtype='object')
 

열 이름이 동일하기 때문에. 이름이 다르면 문제가되지 않습니다.

left.rename(columns={'value':'leftvalue'}).join(right, how='inner')

        leftvalue     value
idxkey                     
B       -0.402655  0.543843
D       -0.524349  0.013135

pd.concat
마지막으로 인덱스 기반 조인의 대안으로 다음을 사용할 수 있습니다 pd.concat.

pd.concat([left, right], axis=1, sort=False, join='inner')

           value     value
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

join='inner'FULL OUTER JOIN이 필요한 경우 생략 (기본값) :

pd.concat([left, right], axis=1, sort=False)

      value     value
A -0.602923       NaN
B -0.402655  0.543843
C  0.302329       NaN
D -0.524349  0.013135
E       NaN -0.326498
F       NaN  1.385076

자세한 내용 은 @piRSquared 의이 표준 게시물을pd.concat 참조하십시오 .


일반화 : merge여러 DataFrames

종종 여러 DataFrame을 병합해야하는 상황이 발생합니다. 순진 히 이것은 merge호출 을 연결하여 수행 할 수 있습니다 .

df1.merge(df2, ...).merge(df3, ...)

그러나 이것은 많은 DataFrames에서 빠르게 벗어날 수 있습니다. 또한 알 수없는 수의 DataFrame을 일반화해야 할 수도 있습니다.

저는 여기에 소개하는 pd.concat여러 방법에 조인 고유 키, DataFrame.join멀티 방법을에 조인 고유하지 않은 키. 먼저 설정입니다.

# Setup.
np.random.seed(0)
A = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'valueA': np.random.randn(4)})    
B = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'valueB': np.random.randn(4)})
C = pd.DataFrame({'key': ['D', 'E', 'J', 'C'], 'valueC': np.ones(4)})
dfs = [A, B, C] 

# Note, the "key" column values are unique, so the index is unique.
A2 = A.set_index('key')
B2 = B.set_index('key')
C2 = C.set_index('key')

dfs2 = [A2, B2, C2]

고유 키 (또는 인덱스)에 대한 다중 병합

키 (여기서 키는 열 또는 인덱스 일 수 있음)가 고유 한 경우 pd.concat. pd.concat인덱스에서 DataFrames조인합니다 .

# merge on `key` column, you'll need to set the index before concatenating
pd.concat([
    df.set_index('key') for df in dfs], axis=1, join='inner'
).reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# merge on `key` index
pd.concat(dfs2, axis=1, sort=False, join='inner')

       valueA    valueB  valueC
key                            
D    2.240893 -0.977278     1.0

join='inner'FULL OUTER JOIN은 생략 합니다. LEFT 또는 RIGHT OUTER 조인을 지정할 수 없습니다 (필요한 경우 join아래에 설명 된대로 사용).

중복 된 키에 대한 다중 병합

concat빠르지 만 단점이 있습니다. 중복을 처리 할 수 ​​없습니다.

A3 = pd.DataFrame({'key': ['A', 'B', 'C', 'D', 'D'], 'valueA': np.random.randn(5)})
pd.concat([df.set_index('key') for df in [A3, B, C]], axis=1, join='inner')
ValueError: Shape of passed values is (3, 4), indices imply (3, 2)

이 상황에서 우리가 사용할 수있는 join이 고유하지 않은 키를 처리 할 수 있기 때문에 (주 join자신의 인덱스에 DataFrames에 합류를, 그것은 호출 merge후드와 LEFT OUTER를 수행 별도로 명시하지 않는 한 가입).

# join on `key` column, set as the index first
# For inner join. For left join, omit the "how" argument.
A.set_index('key').join(
    [df.set_index('key') for df in (B, C)], how='inner').reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# join on `key` index
A3.set_index('key').join([B2, C2], how='inner')

       valueA    valueB  valueC
key                            
D    1.454274 -0.977278     1.0
D    0.761038 -0.977278     1.0
62 eliu Apr 26 2019 at 06:43

의 추가 시각적보기입니다 pd.concat([df0, df1], kwargs). kwarg axis=0또는 axis=1'의 의미는 df.mean()or 만큼 직관적이지 않습니다.df.apply(func)


5 GonçaloPeres龚燿禄 Aug 10 2020 at 17:13

이 답변에서는 pandas.concat.

DataFrames동일한 열 이름으로 다음 을 고려하십시오 .

Preco2018 크기 (8784, 5)

Preco 2019 및 크기 (8760, 5)

열 이름이 동일합니다.

을 사용하여 pandas.concat간단히 결합 할 수 있습니다.

import pandas as pd

frames = [Preco2018, Preco2019]

df_merged = pd.concat(frames)

결과적으로 다음 크기 (17544, 5)의 DataFrame이 생성됩니다.

시각화하려면 다음과 같이 작동합니다.

( 출처 )