[python] 팬더 병합 101

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

… 그리고 더. 팬더 병합 기능의 다양한 측면에 대해 묻는 반복되는 질문을 보았습니다. 오늘날의 병합 및 다양한 사용 사례에 관한 대부분의 정보는 수십 가지의 나쁜 말로 표현할 수없는 게시물에 걸쳐 있습니다. 여기서 목표는 후손에 대한 더 중요한 요점을 정리하는 것입니다.

이 QnA는 일반적인 팬더 관용구에 대한 일련의 유용한 사용자 안내서의 다음 편입니다. ( 이 글은 피벗대한 게시물과 연결 에 대한 게시물을 참조하십시오 .

이 게시물이되고 있습니다 하지 대체 될 운명 문서 , 그래서 그뿐만 아니라 읽으십시오를! 일부 예제는 거기에서 가져옵니다.



답변

이 글은 독자들에게 판다와의 SQL 맛 병합, 사용법, 사용하지 않을 때의 입문서를 제공하는 것을 목표로합니다.

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

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

    • 다른 열 이름과 병합
    • 출력에서 중복 병합 키 열 피하기
  • 다른 조건에서 인덱스와 병합
    • 효과적으로 명명 된 인덱스를 사용하여
    • 하나의 인덱스와 다른 열의 병합 키
  • 열과 인덱스에서 다 방향 병합 (고유 및 비 고유)
  • 에 주목할만한 대안 mergejoin

이 게시물에서 다루지 않을 내용 :

  • 성능 관련 토론 및 타이밍 (현재) 적절한 경우 더 나은 대안에 대한 언급이 가장 눈에.니다.
  • 접미사 처리, 추가 열 제거, 출력 이름 바꾸기 및 기타 특정 사용 사례. 그것을 다루는 다른 (읽기 : 더 나은) 게시물이 있으므로 알아 내십시오!

참고
달리 지정하지 않는 한, 대부분의 예제는 다양한 기능을 보여 주면서 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으로 대체 된 결 측값을 나타냅니다.

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-왼쪽 제외, 오른쪽 제외 및 전체 제외 / ANTI 가입

두 단계로 왼쪽 제외 조인오른쪽 제외 조인 이 필요한 경우 .

왼쪽 제외 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

마찬가지로, 오른쪽 제외 조인의 경우

(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 keyLeftrighthas keyRight대신 key) 다음 left_onright_on같이 대신 및 인수 로 지정해야합니다 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왼쪽 외부 가입은 기본적으로 수행되므로 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

그렇지 않으면 오류가 발생 하므로 lsuffixand rsuffix인수 를 지정해야합니다 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다중 DataFrame

종종 여러 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'전체 외부 참여를 생략하십시오 . 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을 수행함 ).

# 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


답변

에 대한 보충적인 시각 pd.concat([df0, df1], kwargs). 공지 사항, kwarg 것을 axis=0또는 axis=1‘의 의미처럼 직관적으로하지 않습니다 df.mean()또는df.apply(func)


pd.concat ([df0, df1])


답변