판다 병합 101
- 팬더 로 (
INNER
| (LEFT
|RIGHT
|FULL
)OUTER
) 를 수행하는 방법은JOIN
무엇입니까? - 병합 후 누락 된 행에 대한 NaN을 추가하려면 어떻게합니까?
- 병합 후 NaN을 제거하려면 어떻게합니까?
- 인덱스에 병합 할 수 있습니까?
- 팬더와 교차 결합 하시겠습니까?
- 여러 DataFrame을 어떻게 병합합니까?
merge
?join
?concat
?update
? WHO? 뭐? 왜?!
... 그리고 더. pandas 병합 기능의 다양한 측면에 대해 묻는 이러한 반복되는 질문을 보았습니다. 오늘날 병합 및 다양한 사용 사례와 관련된 대부분의 정보는 단어가 잘못되고 검색 할 수없는 수십 개의 게시물에 조각화되어 있습니다. 여기서의 목표는 후세에 대한 더 중요한 몇 가지 사항을 수집하는 것입니다.
이 글 상품 문의 글이 일반적인 팬더 관용구에 도움이 사용자 가이드 시리즈의 다음 분할 될 운명이된다 ( 회전이 게시물에 , 및 연결에이 게시물 나중에 내가에 접촉 될 것이다).
이 게시물은 문서를 대체하기위한 것이 아니므 로이 게시물도 읽어보십시오! 여기에서 일부 예제를 가져 왔습니다.
답변
이 게시물은 독자들에게 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
이 수익률 만 행 left
과 right
공통 (이 예에서는, "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 JOIN 과 RIGHT-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
키 열의 다른 이름
키 열의 이름이 다르게 지정되면 (예 : left
has keyLeft
, right
has keyRight
대신 key
) 다음 대신 left_on
및 right_on
as 인수 를 지정해야합니다 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
출력에서 중복 키 열 방지
keyLeft
from left
및 keyRight
from에서 병합 할 때 출력에 또는 right
둘 중 하나만 원하는 경우 (둘 다 아님) 인덱스를 예비 단계로 설정하여 시작할 수 있습니다.keyLeft
keyRight
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_on
및 right_on
).
left.merge(right, on=['key1', 'key2'] ...)
또는 이름이 다른 경우
left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])
기타 유용한 merge*
작동 및 기능
인덱스에서 Series와 DataFrame 병합 : 이 답변을 참조하십시오 .
게다가
merge
,DataFrame.update
그리고DataFrame.combine_first
특정 경우에 하나의 DataFrame을 다른 DataFrame으로 업데이트하는데도 사용됩니다.pd.merge_ordered
정렬 된 JOIN에 유용한 함수입니다.pd.merge_asof
(읽기 : merge_asOf)는 대략적인 조인에 유용 합니다.
이 섹션은 기본 사항 만 다루며 식욕을 돋우도록 설계되었습니다. 더 많은 예제와 사례를 들어, 참조 에 대한 문서를 merge
, join
그리고concat
뿐만 아니라 기능 사양에 대한 링크로.
인덱스 기반 * -JOIN (+ 인덱스-열 merge
s)
설정
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_on
과 right_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
그렇지 않으면 오류가 발생 하므로 lsuffix
및 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
여러 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
의 추가 시각적보기입니다 pd.concat([df0, df1], kwargs)
. kwarg axis=0
또는 axis=1
'의 의미는 df.mean()
or 만큼 직관적이지 않습니다.df.apply(func)
이 답변에서는 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이 생성됩니다.
시각화하려면 다음과 같이 작동합니다.
( 출처 )