2017-11-01 1 views
1

2 개의 레벨과 하나의 3 개의 멀티 인덱스 데이터 프레임이 있습니다. 처음 두 레벨은 두 데이터 프레임 모두에서 일치합니다. 두 번째 데이터 프레임에서 첫 번째 두 인덱스 수준이 일치하는 첫 번째 데이터 프레임에서 모든 값을 찾고 싶습니다. 제 2 데이터 프레임은 제 3 레벨을 갖지 않는다.팬더 (Pandas) : 일부 레벨이 일치하지 않을 때 하나의 멀티 인덱스 데이터 프레임을 다른 멀티 인덱스와 슬라이스

가장 가까운 대답은 다음과 같습니다. How to slice one MultiIndex DataFrame with the MultiIndex of another - 그러나 설정이 약간 다르며이 경우 번역하지 않는 것 같습니다.

지금 내가이 일치 df_1 모든 값을 찾고 싶은 원래 인덱스

df_2_selection = df_2[(df_2 > 1).any(axis=1)] 
print df_2_selection 

       0   1   2   3 
bar two -0.849186 -2.455453 0.790439 1.134282 
baz one -0.143299 2.372440 -0.161744 0.919658 

의 일부를 반환, 두 번째, dataframe를 조회

array_1 = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']), 
np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']), 
np.array(['a', 'a','a', 'a','b','b','b','b' ])] 

array_2 = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']), 
     np.array(['one', 'two', 'three', 'one', 'two', 'two', 'one', 'two'])] 

df_1 = pd.DataFrame(np.random.randn(8,4), index=array_1).sort_index() 

print df_1 
        0   1   2   3 
bar one a 1.092651 -0.325324 1.200960 -0.790002 
    two a -0.415263 1.006325 -0.077898 0.642134 
baz one a -0.343707 0.474817 0.396702 -0.379066 
    two a 0.315192 -1.548431 -0.214253 -1.790330 
foo one b 1.022050 -2.791862 0.172165 0.924701 
    two b 0.622062 -0.193056 -0.145019 0.763185 
qux one b -1.241954 -1.270390 0.147623 -0.301092 
    two b 0.778022 1.450522 0.683487 -0.950528 

df_2 = pd.DataFrame(np.random.randn(8,4), index=array_2).sort_index() 

print df_2 

        0   1   2   3 
bar one -0.354889 -1.283470 -0.977933 -0.601868 
    two -0.849186 -2.455453 0.790439 1.134282 
baz one -0.143299 2.372440 -0.161744 0.919658 
    three -1.008426 -0.116167 -0.268608 0.840669 
foo two -0.644028 0.447836 -0.576127 -0.891606 
    two -0.163497 -1.255801 -1.066442 0.624713 
qux one -1.545989 -0.422028 -0.489222 -0.357954 
    two -1.202655 0.736047 -1.084002 0.732150 

아래의 설정을 고려 인덱스가 df_2에 있습니다. 처음 두 레벨은 정렬되지만 세 번째 레벨은 정렬되지 않습니다.

이 문제는 인덱스가 줄을, 그리고 또한 내가 df_1[df_1.index.isin(df_2_selection.index.get_level_values(0),level = 0)] 같은과 수준 중 하나와 일치 thhe 값을 찾을 수 있습니다 df_1.loc[df_2_selection.index] #this works if indexes are the same

처럼 무언가에 의해 해결 될 수 있지만,이 문제가 해결되지 않을 때 쉽게 .

원하는 기능을 제공하지 않습니다 함께이 문을 체인으로 연결

df_1[(df_1.index.isin(df_2_selection.index.get_level_values(0),level = 0)) & (df_1.index.isin(df_2_selection.index.get_level_values(1),level = 1))]

내가의 라인을 따라 뭔가 상상 :하지 않은 모두의 나는 많은 다른 방법을 시도

df_1_select = df_1[(df_1.index.isin(
    df_2_selection.index.get_level_values([0,1]),level = [0,1])) #Doesnt Work 

print df_1_select 

        0   1   2   3 
bar two a -0.415263 1.006325 -0.077898 0.642134 
baz one a -0.343707 0.474817 0.396702 -0.379066 

을, 내가 원하는 방식으로 정확하게 일했다. 당신의 배려에 감사합니다.

편집 :

df_1.loc[pd_idx[df_2_selection.index.get_level_values(0),df_2_selection.index.get_level_values(1),:],:] 또한

내가 행만 두 수준의 경기를 원하는 작동하지 않습니다. 어느 레벨이 일치하는지 알 수 없습니다.

편집 2 :이 솔루션은 사람이 게시 된 이후이

id=[x+([x for x in df_1.index.levels[-1]]) for x in df_2_selection.index.values] 

pd.concat([df_1.loc[x] for x in id]) 

실제로 작동 않는 삭제 한 사람! 그러나 대용량 데이터 프레임에서는 엄청나게 느립니다. 새로운 방법/속도 향상에 대한 도움은 크게 감사하겠습니다.

+0

당신은 의미합니까 "나는'df_2_selection'에서 발견 된 인덱스와 일치 df_1' '의 모든 값을 찾을 싶습니다"을? –

+0

네, 그게 정확히 무슨 뜻입니까. 혼란스러운 문구에 대한 미안합니다 – user2259475

답변

1

.

   0   1   2   3 
foo two -0.530151 0.932007 -1.255259 2.441294 
qux one 2.006270 1.087412 -0.840916 -1.225508 

와 병합 :

lvls = ["level_0","level_1"] 

(df_1.reset_index() 
.merge(df_2_selection.reset_index()[lvls], on=lvls) 
.set_index(["level_0","level_1","level_2"]) 
.rename_axis([None]*3) 
) 

출력 :

    0   1   2   3 
foo two b -0.112696 0.287421 -0.380692 -0.035471 
qux one b 0.658227 0.632667 -0.193224 1.073132 

참고 : rename_axis() 파트 단지 레벨 이름을 제거하고, 예로서 df_2_selection 함께

level_0. 순수하게 화장품이며 실제 매칭 절차를 수행 할 필요가 없습니다.

+0

이 솔루션은 매우 효과적입니다! 감사! 나는이 기능이 multiindex 객체에 내장 될 것이라고 생각했는데, 그 이유는 알지 못합니다. – user2259475

+0

좋습니다! 이 답변으로 질문이 해결 된 경우 답변의 왼쪽에있는 체크 표시를 클릭하여 동의 표시를하십시오. –

0

이 시도 : 당신은 reset_index()merge()을 사용할 수 있습니다

pd.concat([ 
    df_1.xs(key, drop_level=False) 
    for key in df_2_selection.index.values]) 
+0

이 작품도 고마워! 그러나 위의 솔루션 (인덱스 재설정)은 더 큰 데이터 세트에서 더 빠릅니다. – user2259475

관련 문제