2015-05-05 16 views
8

Jestem nowy pand i nie wydaje się uzyskać to do pracy z funkcją łączenia:pandy LEFT JOIN i zaktualizować istniejącą kolumna

>>> left  >>> right 
    a b c  a c d 
0 1 4 9 0 1 7 13 
1 2 5 10 1 2 8 14 
2 3 6 11 2 3 9 15 
3 4 7 12  

Z LEFT JOIN na kolumnie chciałbym zaktualizować wspólny kolumny PRZY ZAŁĄCZONYCH KLUCZACH. Uwaga ostatnia wartość w kolumnie c pochodzi z LEWEJ tabeli, ponieważ nie ma zgodności.

>>> final  
    a b c d 
0 1 4 7 13 
1 2 5 8 14 
2 3 6 9 15 
3 4 7 12 NAN 

Jak powinienem to zrobić przy funkcji łączenia Pand? Dziękuję Ci.

Odpowiedz

11

Jednym ze sposobów, aby to zrobić, to ustawić kolumnę jako indeks i update:

In [11]: left_a = left.set_index('a') 

In [12]: right_a = right.set_index('a') 

Uwaga: update tylko nie lewe sprzężenie (nie łączy), tak samo jak zestaw_indeksów, musisz również uwzględnić dodatkowe kolumny nieobecne w left_a.

In [13]: res = left_a.loc[:, left_a.columns.union(right_a.columns)] 

In [14]: res.update(right_a) 

In [15]: res 
Out[15]: 
    b c d 
a 
1 4 7 13 
2 5 8 14 
3 6 9 15 
4 7 12 NaN 
+0

Dziękujemy! Nie rozumiem, dlaczego to nie zostało wbudowane. – iwbabn

+1

Ostrzeżenie dla tych, którzy implementują to rozwiązanie: W pewnych warunkach zmienne typu dpt są zmienione na float! http://stackoverflow.com/questions/17398216/unwanted-type-conversion-in-pandas-dataframe-update – ssoler

8

Można użyć merge() między left i right z how='left' na 'a' kolumna.

In [74]: final = left.merge(right, on='a', how='left') 

In [75]: final 
Out[75]: 
    a b c_x c_y d 
0 1 4 9 7 13 
1 2 5 10 8 14 
2 3 6 11 9 15 
3 4 7 12 NaN NaN 

Wymień NaN wartość z c_y z c_x wartości

In [76]: final['c'] = final['c_y'].fillna(final['c_x']) 

In [77]: final 
Out[77]: 
    a b c_x c_y d c 
0 1 4 9 7 13 7 
1 2 5 10 8 14 8 
2 3 6 11 9 15 9 
3 4 7 12 NaN NaN 12 

upuść niechciane kolumny, a ty the resilt

In [79]: final.drop(['c_x', 'c_y'], axis=1) 
Out[79]: 
    a b d c 
0 1 4 13 7 
1 2 5 14 8 
2 3 6 15 9 
3 4 7 NaN 12 
+0

To fillna (z inną kolumną) jest całkiem schludna! – fixxxer

+0

Ta metoda jest lepsza niż akceptowana, ponieważ nie zależy od dwóch elementów DataFrame mających wspólną zmienną sprzężenia ("a" w tym przykładzie). – blahblahetcetc

+0

Konsekwentnie dostaję ten błąd, gdy używam tego kodu: FutureWarning: Przechodząc listę-lubi do .loc lub [] z brakującą etykietą podniesie KeyError w przyszłości, możesz użyć .reindex() jako alternatywy. My tylko myśl, że moje dfs może nie dzielić te same kolumny? Czy nie jest to jednak to, na co pierwotna odpowiedź miała odpowiadać? – conchoecia

1

Oto sposób to zrobić z join:

In [632]: t = left.set_index('a').join(right.set_index('a'), rsuffix='_right') 

In [633]: t 
Out[633]: 
    b c c_right d 
a      
1 4 9  7 13 
2 5 10  8 14 
3 6 11  9 15 
4 7 12  NaN NaN 

Teraz chcemy ustawić wartości puste o wartości c_right (która pochodzi z ramki danych right) z wartościami z kolumny c z ramki danych left. Zaktualizowany poniższy proces metoda biorąc od odpowiedzi @John Galt za

In [657]: t['c_right'] = t['c_right'].fillna(t['c']) 

In [658]: t 
Out[658]: 
    b c c_right d 
a      
1 4 9  7 13 
2 5 10  8 14 
3 6 11  9 15 
4 7 12  12 NaN 

In [659]: t.drop('c_right', axis=1) 
Out[659]: 
    b c d 
a   
1 4 9 13 
2 5 10 14 
3 6 11 15 
4 7 12 NaN