Ищем самый быстрый способ найти точное перекрытие между двумя массивами равной длины в numpy - PullRequest
3 голосов
/ 27 января 2010

Я ищу оптимальный (самый быстрый) способ найти точное совпадение между двумя массивами в numpy. Даны два массива x и y

x = array([1,0,3,0,5,0,7,4],dtype=int)
y = array([1,4,0,0,5,0,6,4],dtype=int)

То, что я хочу получить, это массив одинаковой длины, содержащий только числа из обоих векторов, которые равны:

array([1,0,0,0,5,0,0,4])

Сначала я попробовал

x&y
array([1,0,0,0,5,0,6,4])

Тогда я понял, что это всегда верно для двух чисел, если они> 0.

Ответы [ 3 ]

6 голосов
/ 27 января 2010
result = numpy.where(x == y, x, 0)

Для объяснения смотрите документацию numpy.where. По существу, numpy.where(a, b, c) для условия a возвращает массив формы a и со значениями от b или c, в зависимости от того, является ли соответствующий элемент a истинным или нет. b или c могут быть скалярами.

Кстати, x & y не обязательно «всегда верно» для двух положительных чисел. Это делает побитовым и для элементов в x и y:

x = numpy.array([2**p for p in xrange(10)])
# x is [  1   2   4   8  16  32  64 128 256 512]
y = x - 1
# y is [  0   1   3   7  15  31  63 127 255 511]
x & y
# result: [0 0 0 0 0 0 0 0 0 0]

Это потому, что побитовое представление каждого элемента в x имеет вид 1, за которым следуют n нулей, а соответствующий элемент в y равен n 1 с. Как правило, для двух ненулевых чисел a и b, a & b может равняться нулю или отличным от нуля, но необязательно равным a или b.

.
2 голосов
/ 30 января 2010

Использование numpy.where является наиболее общим решением. но в данном конкретном случае, и поскольку это полезная практика программирования, вы можете использовать x==y в качестве маски:

mask = x==y  
# mask is  array([ True, False, False,  True,  True,  True, False,  True], dtype=bool)

xf = mask * x
# xf is array([1, 0, 0, 0, 5, 0, 0, 4])

или напрямую

xf = (x==y) * x

представьте теперь некоторые данные X (например, 1D для звука, 2D для изображения, 3D для фильма и т. Д ...)

(X<1) * -1. + (X>1) * 1.

возвращает данные со значениями -1 для амплитуды ниже 1 и 1. в противном случае.

0 голосов
/ 10 июня 2013

попробуйте numpy.in1d ​​... из документации ....

Проверьте, присутствует ли каждый элемент одномерного массива во втором массиве.

Возвращает логический массив той же длины, что и ar1, что является True где элемент ar1 находится в ar2 и False в противном случае.

Параметры

ar1: массив_подобный, форма (M,) Входной массив. ar2: array_like Значения, по которым проверяется каждое значение ar1. accept_unique: bool, необязательно Если True, то входные массивы оба предполагаются уникальными, что может ускорить расчет. По умолчанию установлено значение False.

Возвращает

маска: ndarray из bools, форма (M,) Значения ar1[mask] находятся в ar2.

См. Также

numpy.lib.arraysetops: модуль с рядом других функций для выполнение операций над множествами над массивами.

Примечания

in1d можно рассматривать как вариант поэлементной функции ключевое слово python in, для одномерных последовательностей. in1d(a, b) примерно эквивалентно np.array([item in b for item in a]).

.. версия добавлена ​​:: 1.4.0

Примеры

test = np.array([0, 1, 2, 5, 0])
states = [0, 2]
mask = np.in1d(test, states)
mask
    array([ True, False,  True, False,  True], dtype=bool)
test[mask]
    array([0, 2, 0])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...