Các giải pháp hiện đang được lựa chọn tạo ra kết quả không chính xác. Để giải quyết chính xác vấn đề này, chúng tôi có thể thực hiện nối từ trái df1
sang df2
, trước tiên hãy đảm bảo chỉ nhận các hàng duy nhất chodf2
.
Trước tiên, chúng ta cần sửa đổi DataFrame gốc để thêm hàng với dữ liệu [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
Thực hiện nối trái, loại bỏ trùng lặp sao df2
cho mỗi hàng df1
nối với đúng 1 hàng df2
. Sử dụng tham số indicator
để trả về một cột phụ cho biết hàng đó được lấy từ bảng nào.
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
Tạo một điều kiện boolean:
df_all['_merge'] == 'left_only'
0 False
1 False
2 False
3 True
4 True
5 True
Name: _merge, dtype: bool
Tại sao các giải pháp khác là sai
Một vài giải pháp mắc cùng một lỗi - họ chỉ kiểm tra xem mỗi giá trị độc lập trong mỗi cột chứ không phải cùng một hàng. Thêm hàng cuối cùng, là duy nhất nhưng có các giá trị từ cả hai cột df2
để lộ lỗi:
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
Giải pháp này nhận được kết quả sai tương tự:
df1.isin(df2.to_dict('l')).all(1)