In [3]: arr1 = np.array([
...: [1, 2, 3, 4],
...: [2, 3, 1, 4],
...: [2, 4, 1, 5],
...: ])
...:
...: arr2 = np.array([
...: [2, 4, 1, 5],
...: [2, 1, 3, 5],
...: [1, 2, 3, 4],
...: ])
транслируемое равенство, за которым следует соответствующее сочетание all
и any
:
In [8]: (arr1[:,None,:]==arr2[None,:,:]).shape
Out[8]: (3, 3, 4)
In [9]: (arr1[:,None,:]==arr2[None,:,:]).all(axis=2)
Out[9]:
array([[False, False, True],
[False, False, False],
[ True, False, False]])
In [10]: (arr1[:,None,:]==arr2[None,:,:]).all(axis=2).any(axis=0)
Out[10]: array([ True, False, True])
In [12]: arr1[_]
Out[12]:
array([[1, 2, 3, 4],
[2, 4, 1, 5]])
С наборами
In [19]: set([tuple(row) for row in arr1])
Out[19]: {(1, 2, 3, 4), (2, 3, 1, 4), (2, 4, 1, 5)}
In [20]: set([tuple(row) for row in arr2])
Out[20]: {(1, 2, 3, 4), (2, 1, 3, 5), (2, 4, 1, 5)}
In [21]: _19.intersection(_20)
Out[21]: {(1, 2, 3, 4), (2, 4, 1, 5)}
===
Если я расширю arr2
до 4 строк:
...: arr2 = np.array([
...: [2, 4, 1, 5],
...: [2, 1, 3, 5],
...: [1, 2, 3, 4],
...: [1, 1, 1, 1],
...: ])
In [34]: (arr1[:,None,:]==arr2[None,:,:]).all(axis=2).any(axis=0)
Out[34]: array([ True, False, True, False])
any
на 0 создаст 4-элементный массив, который должен использоваться для индексации arr2
(а не arr1
, как я изначально ):
In [35]: arr2[_]
Out[35]:
array([[2, 4, 1, 5],
[1, 2, 3, 4]])
Или any
по другой оси:
In [36]: (arr1[:,None,:]==arr2[None,:,:]).all(axis=2).any(axis=1)
Out[36]: array([ True, False, True])
In [37]: arr1[_]
Out[37]:
array([[1, 2, 3, 4],
[2, 4, 1, 5]])
all
создает (в данном случае) массив (3,4):
In [38]: (arr1[:,None,:]==arr2[None,:,:]).all(axis=2)
Out[38]:
array([[False, False, True, False],
[False, False, False, False],
[ True, False, False, False]])
any
может уменьшать строки или столбцы.