otrzymuje dwie dataframes jak poniżej:jak wykonać wewnętrzną lub zewnętrzną przyłączyć od DataFrames z Pand na non-uproszczone kryterium
>>> import pandas as pd
>>> df_a = pd.DataFrame([{"a": 1, "b": 4}, {"a": 2, "b": 5}, {"a": 3, "b": 6}])
>>> df_b = pd.DataFrame([{"c": 2, "d": 7}, {"c": 3, "d": 8}])
>>> df_a
a b
0 1 4
1 2 5
2 3 6
>>> df_b
c d
0 2 7
1 3 8
chcielibyśmy produkować SQL stylu łączą obu dataframes za pomocą nie- uproszczone kryteria, powiedzmy "df_b.c> df_a.a". Z tego, co mogę powiedzieć, podczas gdy merge()
jest z pewnością częścią rozwiązania, nie mogę go użyć bezpośrednio, ponieważ nie akceptuje on arbitralnych wyrażeń dla kryteriów "ON" (chyba że czegoś mi brakuje?).
W SQL wynik wygląda następująco:
# inner join
sqlite> select * from df_a join df_b on c > a;
1|4|2|7
1|4|3|8
2|5|3|8
# outer join
sqlite> select * from df_a left outer join df_b on c > a;
1|4|2|7
1|4|3|8
2|5|3|8
3|6||
my obecny sposób sprzężenia wewnętrznego jest wytworzenie iloczyn z df_a i df_b dodając kolumnę „1” s do obu następnie używając scalania() w kolumnie "1", a następnie stosując kryteria "c> a".
>>> import numpy as np
>>> df_a['ones'] = np.ones(3)
>>> df_b['ones'] = np.ones(2)
>>> cartesian = pd.merge(df_a, df_b, left_on='ones', right_on='ones')
>>> cartesian
a b ones c d
0 1 4 1 2 7
1 1 4 1 3 8
2 2 5 1 2 7
3 2 5 1 3 8
4 3 6 1 2 7
5 3 6 1 3 8
>>> cartesian[cartesian.c > cartesian.a]
a b ones c d
0 1 4 1 2 7
1 1 4 1 3 8
3 2 5 1 3 8
dla sprzężenia zewnętrznego, nie jestem pewien najlepszym sposobem, jakim Grałem z coraz wewnętrzna przyłączyć, a następnie stosując negację kryteria, aby uzyskać wszystkie inne wiersze, a następnie próbują edytować "negację" ustawioną na oryginale, ale tak naprawdę nie działa.
Edytuj. HYRY odpowiedział na konkretne pytanie, ale potrzebowałem czegoś bardziej ogólnikowego i bardziej wewnętrznego w Pandach API, ponieważ moje kryterium połączenia mogło być wszystkim, a nie tylko jednym porównaniem. Dla outerjoin najpierw Dodaję dodatkowy wskaźnik na „lewej” strony, które będą utrzymywać się po tym, jak zrobić wewnętrzna przyłączyć:
df_a['_left_index'] = df_a.index
następnie robimy kartezjański i uzyskać sprzężenie wewnętrzne:
cartesian = pd.merge(df_a, df_b, left_on='ones', right_on='ones')
innerjoin = cartesian[cartesian.c > cartesian.a]
następnie uzyskać dodatkowe identyfikatory indeksów w „df_a”, że będziemy potrzebować i uzyskać wiersze z „df_a”:
remaining_left_ids = set(df_a['_left_index']).\
difference(innerjoin['_left_index'])
remaining = df_a.ix[remaining_left_ids]
następnie używamy prostą concat(), która zastępuje brakujące kolumny z "NaN" na lewo (myślałem, że to było Nie robi to wcześniej, ale myślę, że to robi):
outerjoin = pd.concat([innerjoin, remaining]).reset_index()
pomysł HYRY do zrobienia kartezjańskiej na przełęcze tylko tych, które musimy porównać na jest w zasadzie prawidłowa odpowiedź, choć w moim konkretnym przypadku może to być trochę trudne do wdrożenia (uogólnione i wszystkie).
pytania:
Jak można produkować "join" z df_1 i df_2 na "c> a"? Czy wykonałbyś ten sam "produkt kartezjański, filtr", czy jest jakiś lepszy sposób na: ?
Jak wytworzysz "lewe połączenie zewnętrzne" tego samego?
nadal analizowania tego, czy jest jakiś sposób, aby osiągnąć ekspresję używając pandy Series (które jest generowane przez wyrażenie jak „df_a.a < df_b.c "? Nie będę miał" a
zzzeek
chociaż tylko pomysł zrobienia kartezjańskiego na colach, potrzebuję zaoszczędzić pamięć, warto zajrzeć do ... – zzzeek