Załóżmy, że mam dwie takie ramki danych:
left = pd.DataFrame({'key1': ['foo', 'bar'], 'lval': [1, 2]})
right = pd.DataFrame({'key2': ['foo', 'bar'], 'rval': [4, 5]})
Chcę je scalić, więc próbuję czegoś takiego:
pd.merge(left, right, left_on='key1', right_on='key2')
I cieszę się
key1 lval key2 rval
0 foo 1 foo 4
1 bar 2 bar 5
Ale próbuję użyć metody łączenia, w którą, jak wierzyłem, podobna jest sytuacja.
left.join(right, on=['key1', 'key2'])
I dostaję to:
//anaconda/lib/python2.7/site-packages/pandas/tools/merge.pyc in _validate_specification(self)
406 if self.right_index:
407 if not ((len(self.left_on) == self.right.index.nlevels)):
--> 408 raise AssertionError()
409 self.right_on = [None] * n
410 elif self.right_on is not None:
AssertionError:
czego mi brakuje?
merge
łączy kolumny zleft
kolumnamiright
, co jest tym, czego chcesz, alejoin(... on=[...])
łączy kolumny zleft
kluczami indeksuright
, co nie jest tym, czego chcesz. Zobacz moją odpowiedź poniżej, aby uzyskać więcej informacji.on
opcję) doother
indeksów. Pamiętaj, indeksy dla dołączenia. Chociaż merge () jest bardziej ogólną metodą.Odpowiedzi:
Zawsze używam
join
indeksów:Tę samą funkcjonalność można uzyskać za pomocą
merge
następujących kolumn:źródło
right
tej samej głębokości ma długośćon
. To ma dla mnie sens. Mogę zaakceptować, że semantyka jest inna. Ale chciałbym wiedzieć, czy mogę uzyskać to samo zachowanie z df.joinpandas.merge()
to podstawowa funkcja używana dla wszystkich zachowań scalania / łączenia.Ramki danych zapewniają metody
pandas.DataFrame.merge()
ipandas.DataFrame.join()
jako wygodny sposób dostępu do możliwościpandas.merge()
. Na przykładdf1.merge(right=df2, ...)
jest równoważne zpandas.merge(left=df1, right=df2, ...)
.Oto główne różnice między
df.join()
idf.merge()
:df1.join(df2)
zawsze łączy się poprzez indeksdf2
, aledf1.merge(df2)
może łączyć się z jedną lub więcej kolumnamidf2
(domyślnie) lub z indeksemdf2
(zright_index=True
).df1.join(df2)
używa indeksudf1
idf1.merge(df2)
używa kolumn (y)df1
. Można to zastąpić, określającdf1.join(df2, on=key_or_keys)
lubdf1.merge(df2, left_index=True)
.df1.join(df2)
domyślnie wykonuje lewe łączenie (zachowuje wszystkie rzędydf1
), aledf.merge
domyślnie wykonuje łączenie wewnętrzne (zwraca tylko pasujące wierszedf1
idf2
).Tak więc ogólne podejście polega na użyciu
pandas.merge(df1, df2)
lubdf1.merge(df2)
. Ale w wielu typowych sytuacjach (utrzymywanie wszystkich wierszydf1
i łączenie z indeksem w środkudf2
) możesz zapisać trochę pisania, używającdf1.join(df2)
zamiast tego.Kilka uwag na temat tych zagadnień z dokumentacji na stronie http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging :
...
źródło
on=key_or_keys
aby zmienić sposób znajdowania wierszy w odpowiedniej tabeli. Tak jednak nie jest.on
Argumentu zmienia się wyszukiwanie na lewym stołem (df1
) z indeksem do kolumny (S). Jednak nawet z tym argumentem odpowiednia tabela (df2
) zostanie dopasowana poprzez jej indeks. (Zobacz ostatni przykład powyżej.)Uważam, że
join()
to tylko wygodna metoda. Spróbujdf1.merge(df2)
zamiast tego, co pozwala określićleft_on
iright_on
:źródło
Z tej dokumentacji
I :
źródło
Jedną z różnic jest to, że
merge
tworzy nowy indeks ijoin
utrzymuje indeks z lewej strony. Może to mieć duży wpływ na twoje późniejsze transformacje, jeśli błędnie założysz, że twój indeks się nie zmieniamerge
.Na przykład:
-
-
-
źródło
on
parametr ma inne znaczenie w obu przypadkachźródło
Mówiąc analogicznie do SQL „Scalanie Pandas oznacza łączenie zewnętrzne / wewnętrzne, a łączenie Pandas jest łączeniem naturalnym”. Dlatego kiedy używasz scalania w pandach, chcesz określić, jakiego rodzaju złączenia sqlish chcesz użyć, podczas gdy używając pand, naprawdę chcesz mieć pasującą etykietę kolumny, aby upewnić się, że się łączy
źródło