IIUC, вы можете попробовать:
df.assign(key=1).merge(df.assign(key=1), on='key')\
.query('A_x != A_y and B_x != B_y').drop('key', axis=1)
Вывод:
A_x B_x A_y B_y
1 1 2 2 3
2 1 2 3 4
3 1 2 4 5
4 2 3 1 2
6 2 3 3 4
7 2 3 4 5
8 3 4 1 2
9 3 4 2 3
11 3 4 4 5
12 4 5 1 2
13 4 5 2 3
14 4 5 3 4
Или для дальнейшей фильтрации использовать неравенства:
df.assign(key=1).merge(df.assign(key=1), on='key')\
.query('A_x < A_y and B_x < B_y').drop('key', axis=1)
Вывод:
A_x B_x A_y B_y
1 1 2 2 3
2 1 2 3 4
3 1 2 4 5
6 2 3 3 4
7 2 3 4 5
11 3 4 4 5
Подробности:
assign
псевдо-ключ и «самостоятельное соединение» с использованием merge
для создания декартового произведения, затем используйте query
для фильтрации результатов и drop
ключ.