Пересечение двумерных массивов - PullRequest
1 голос
/ 15 апреля 2019

Я ищу способ получить пересечение между двумя двумерными numpy.array формы (n_1, m) и (n_2, m).Обратите внимание, что n_1 и n_2 могут различаться, но m одинаково для обоих массивов.Вот два минимальных примера с ожидаемыми результатами:

import numpy as np

array1a = np.array([[2], [2], [5], [1]])
array1b = np.array([[5], [2]])

array_intersect(array1a, array1b)
##  array([[2],
##         [5]])


array2a = np.array([[1, 2], [3, 3], [2, 1], [1, 3], [2, 1]])
array2b = np.array([[2, 1], [1, 4], [3, 3]])

array_intersect(array2a, array2b)
##  array([[2, 1],
##         [3, 3]])

Если кто-то знает, как мне реализовать функцию array_intersect, я был бы очень признателен!

Ответы [ 5 ]

1 голос
/ 15 апреля 2019

Как насчет использования наборов?

import numpy as np

array2a = np.array([[1, 2], [3, 3], [2, 1], [1, 3], [2, 1]])
array2b = np.array([[2, 1], [1, 4], [3, 3]])


a = set((tuple(i) for i in array2a))
b = set((tuple(i) for i in array2b))

a.intersection(b) # {(2, 1), (3, 3)}
0 голосов
/ 16 апреля 2019

Пакет с индексом NUMPY (заявление об отказе: я его автор) был создан с точной целью предоставления такой функциональности выразительным и эффективным способом:

import numpy_indexed as npi
npi.intersect(a, b)

Обратите внимание, чтореализация полностью векторизована;это не циклы над массивами в Python.

0 голосов
/ 15 апреля 2019

Вот способ обойтись без каких-либо циклов или списков, при условии, что у вас установлено scipy (я не проверял скорость):

In [31]: from scipy.spatial.distance import cdist

In [32]: np.unique(array1a[np.where(cdist(array1a, array1b) == 0)[0]], axis=0)
Out[32]: 
array([[2],
       [5]])

In [33]: np.unique(array2a[np.where(cdist(array2a, array2b) == 0)[0]], axis=0)
Out[33]: 
array([[2, 1],
       [3, 3]])
0 голосов
/ 15 апреля 2019

Другой подход заключается в использовании функции вещания

import numpy as np

array2a = np.array([[1, 2], [3, 3], [2, 1], [1, 3], [2, 1]])
array2b = np.array([[2, 1], [1, 4], [3, 3]])

test = array2a[:, None] == array2b
print(array2b[np.all(test.mean(0) > 0, axis = 1)]) # [[2 1]
                                                   # [3 3]]

но это менее читабельно имо. [править]: или используйте уникальную и заданную комбинацию. Короче, есть много вариантов!

0 голосов
/ 15 апреля 2019

Создайте набор кортежей из первого массива и протестируйте каждую строку второго массива.Или наоборот.

def array_intersect(a, b):
    s = {tuple(x) for x in a}
    return np.unique([x for x in b if tuple(x) in s], axis=0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...