Pandas merge를 사용할 때 색인을 유지하는 방법


126

두 개를 병합 DataFrames하고 첫 번째 프레임의 인덱스를 병합 된 데이터 세트의 인덱스로 유지하고 싶습니다 . 그러나 병합을 수행하면 결과 DataFrame에 정수 인덱스가 있습니다. 왼쪽 데이터 프레임에서 인덱스를 유지하도록 지정하려면 어떻게해야합니까?

In [4]: a = pd.DataFrame({'col1': {'a': 1, 'b': 2, 'c': 3}, 
                          'to_merge_on': {'a': 1, 'b': 3, 'c': 4}})

In [5]: b = pd.DataFrame({'col2': {0: 1, 1: 2, 2: 3}, 
                          'to_merge_on': {0: 1, 1: 3, 2: 5}})

In [6]: a
Out[6]:
   col1  to_merge_on
a     1            1
b     2            3
c     3            4

In [7]: b
Out[7]:
   col2  to_merge_on
0     1            1
1     2            3
2     3            5

In [8]: a.merge(b, how='left')
Out[8]:
   col1  to_merge_on  col2
0     1            1   1.0
1     2            3   2.0
2     3            4   NaN

In [9]: _.index
Out[9]: Int64Index([0, 1, 2], dtype='int64')

편집 : 쉽게 재현 할 수있는 예제 코드로 전환


2
특정 열을 병합하는 경우 사용할 인덱스가 명확하지 않습니다 (둘 다 다른 경우).
bonobo

답변:


161
In [5]: a.reset_index().merge(b, how="left").set_index('index')
Out[5]:
       col1  to_merge_on  col2
index
a         1            1     1
b         2            3     2
c         3            4   NaN

참고 : 사이에 여러 개의 일치가있는 경우 일부 왼쪽 병합 작업에 더 많은 행을 끝낼 수 ab당신은 중복 제거 (필요 중복 제거에 대한 문서가 ). 이것이 팬더가 색인을 유지하지 않는 이유입니다.


4
매우 영리한. a.merge (b, how = "left"). set_index (a.index)도 작동하지만 덜 강력 해 보입니다 (첫 번째 부분이 인덱스 값을 재설정하기 전에 a로 잃기 때문입니다.)
DanB

11
이 특별한 경우에는 동등합니다. 그러나 많은 병합 작업의 경우 결과 프레임에는 원래 a프레임 과 동일한 수의 행이 없습니다 . reset_index는 인덱스를 일반 열로 이동하고 병합 후이 열에서 set_index는 병합 작업으로 인해 a 행이 복제 / 제거 될 때도 처리합니다.
Wouter Overmeire 2012 년

1
@Wouter 왼쪽 병합이 기본적으로 다시 색인화되는 이유를 알고 싶습니다. 자세한 내용은 어디에서 확인할 수 있습니까?
Matthew

7
좋은! 인덱스 이름을 명시 적으로 지정하지 않으려면 a.reset_index().merge(b, how="left").set_index(a.index.names).
Truls

3
Pandas는 API가 다시 발생한다고 잘못 생각했습니다.
Henry Henrinson 19

7

왼쪽 데이터 프레임에 인덱스 복사본을 만들고 병합 할 수 있습니다.

a['copy_index'] = a.index
a.merge(b, how='left')

이 간단한 방법은 큰 데이터 프레임으로 작업하고 pd.merge_asof()(또는 dd.merge_asof())을 사용하는 동안 매우 유용하다는 것을 알았습니다 .

이 접근 방식은 인덱스 재설정이 비용이 많이 드는 경우 (대용량 데이터 프레임) 더 우수합니다.


1
이것이 최고의 답변입니다. 병합 중에 이전 인덱스를 보존하려는 이유는 여러 가지가 있습니다 (허용 된 답변은 인덱스를 보존하지 않고 재설정 만합니다). 2 개 이상의 데이터 프레임 등을 병합하려고 할 때 도움이됩니다.
Marses

2
우수한 솔루션는 (원본) 인덱스 이름 유지로
Martien Lubberink

upvoted하지만 단지 멀티 인덱스를 사용하는 경우, 사용자의 인덱스가 하나의 열에서 튜플로 저장 될 경고, 조심은 [copy_index]라고
geekidharsh

6

비 pd.merge 솔루션이 있습니다. map및 사용set_index

In [1744]: a.assign(col2=a['to_merge_on'].map(b.set_index('to_merge_on')['col2']))
Out[1744]:
   col1  to_merge_on  col2
a     1            1   1.0
b     2            3   2.0
c     3            4   NaN

그리고 index인덱스에 대한 더미 이름을 도입하지 않습니다 .


1
이것은 다중 인덱스와 같은 엣지 케이스에서 더 잘 작동하기 때문에 허용되는 답변보다 우수합니다. 누구든지 이것에 대해 언급 할 수 있습니까?
BallpointBen

1
질문, 여러 열을 할당해야하는 경우이 방법이 작동합니까 아니면 하나의 필드로만 제한됩니까?
Yuca

@Yuca : 여러 열의 하위 집합을 사용 pd.Dataframe하면 pd.Series. 이 .map()메서드는 pd.Series. 이것은 a[['to_merge_on_1', 'to_merge_on_2']].map(...)작동하지 않는다는 것을 의미합니다 .
Dataman

4
df1 = df1.merge(
        df2, how="inner", left_index=True, right_index=True
    )

이를 통해 df1의 색인을 유지할 수 있습니다.


작동하는 것 on=list_of_cols]같지만와 함께 사용 하면 문서 와 모순 If joining columns on columns, the DataFrame indexes *will be ignored*됩니다. 인덱스와 열을 사용하는 것이 우선입니까?
Itamar Katz

0

내가 다른 해결책을 생각해 냈다고 생각합니다. 왼쪽 테이블의 인덱스를 기반으로 한 열 값에 인덱스 값과 오른쪽 테이블을 조인했습니다. 내가 한 일은 정상적인 병합이었습니다.

First10ReviewsJoined = pd.merge(First10Reviews, df, left_index=True, right_on='Line Number')

그런 다음 병합 된 테이블에서 새 인덱스 번호를 검색하여 Sentiment Line Number라는 새 열에 넣습니다.

First10ReviewsJoined['Sentiment Line Number']= First10ReviewsJoined.index.tolist()

그런 다음 Line Number (왼쪽 테이블 인덱스에서 조인 한 열 값)라는 기존 열을 기반으로 인덱스를 원래의 왼쪽 테이블 인덱스로 다시 수동 설정합니다.

First10ReviewsJoined.set_index('Line Number', inplace=True)

그런 다음 행 번호의 색인 이름을 제거하여 공백으로 둡니다.

First10ReviewsJoined.index.name = None

아마도 약간의 해킹이지만 잘 작동하고 비교적 간단하게 보입니다. 또한 데이터가 중복되거나 엉망이 될 위험을 줄여줍니다. 모든 것이 이해되기를 바랍니다.


0

또 다른 간단한 옵션은 인덱스의 이름을 이전과 같이 바꾸는 것입니다.

a.merge(b, how="left").set_axis(a.index)

merge는 데이터 프레임 'a'에서 순서를 유지하지만 인덱스를 재설정하여 set_axis를 사용하도록 저장합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.