Aktualnie wybrane rozwiązanie daje nieprawidłowe wyniki. Aby poprawnie rozwiązać ten problem, możemy wykonać lewe połączenie od df1do df2, upewniając się, że najpierw otrzymamy tylko unikalne wiersze df2.
Najpierw musimy zmodyfikować oryginalny DataFrame, aby dodać wiersz z danymi [3, 10].
df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3],
'col2' : [10, 11, 12, 13, 14, 10]})
df2 = pd.DataFrame(data = {'col1' : [1, 2, 3],
'col2' : [10, 11, 12]})
df1
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
5 3 10
df2
col1 col2
0 1 10
1 2 11
2 3 12
Wykonaj lewe łączenie, eliminując duplikaty df2, aby każdy rząd df1złączeń miał dokładnie 1 wiersz df2. Użyj tego parametru, indicatoraby zwrócić dodatkową kolumnę wskazującą, z której tabeli pochodzi wiersz.
df_all = df1.merge(df2.drop_duplicates(), on=['col1','col2'],
how='left', indicator=True)
df_all
col1 col2 _merge
0 1 10 both
1 2 11 both
2 3 12 both
3 4 13 left_only
4 5 14 left_only
5 3 10 left_only
Utwórz warunek logiczny:
df_all['_merge'] == 'left_only'
0 False
1 False
2 False
3 True
4 True
5 True
Name: _merge, dtype: bool
Dlaczego inne rozwiązania są złe
Kilka rozwiązań popełnia ten sam błąd - sprawdzają tylko, czy każda wartość jest niezależnie w każdej kolumnie, a nie razem w tym samym wierszu. Dodanie ostatniego wiersza, który jest unikalny, ale zawiera wartości z obu kolumn, df2ujawnia błąd:
common = df1.merge(df2,on=['col1','col2'])
(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))
0 False
1 False
2 False
3 True
4 True
5 False
dtype: bool
To rozwiązanie otrzymuje ten sam zły wynik:
df1.isin(df2.to_dict('l')).all(1)