Pythonic способ проверить, находится ли строка в массиве - PullRequest
11 голосов
/ 03 июля 2011

Это кажется простым вопросом, но я не смог найти хорошего ответа.

Я ищу питонский способ проверить, содержит ли двумерный массив с нулевыми данными заданную строку.Например:

myarray = numpy.array([[0,1],
                       [2,3],
                       [4,5]])

myrow1 = numpy.array([2,3])
myrow2 = numpy.array([2,5])
myrow3 = numpy.array([0,3])
myrow4 = numpy.array([6,7])

Учитывая myarray, я хочу написать функцию, которая возвращает True, если я проверяю myrow1, и False, если я проверяю myrow2, myrow3 и myrow4.

Я пытался "в ключевом слове ", и это не дало мне ожидаемых результатов:

>>> myrow1 in myarray
True
>>> myrow2 in myarray
True
>>> myrow3 in myarray
True
>>> myrow4 in myarray
False

Кажется, что проверяется только один или несколько элементов, не совпадают ли все элементы.Может кто-нибудь объяснить, почему это происходит?

Я могу сделать этот тестовый элемент за элементом, что-то вроде этого:

def test_for_row(array,row):
    numpy.any(numpy.logical_and(array[:,0]==row[0],array[:,1]==row[1]))

Но это не очень питонно и становится проблематичным, если в строках много элементов,Должно быть более элегантное решение.Любая помощь приветствуется!

Ответы [ 5 ]

5 голосов
/ 03 июля 2011

Вопрос SO, приведенный ниже, должен помочь вам, но в основном вы можете использовать:

any((myrow1 == x).all() for x in myarray)

Numpy.Array в списке Python?

3 голосов
/ 03 июля 2011

Вы можете просто вычесть свою тестовую строку из массива. Затем найдите нулевые элементы и суммируйте по столбцу. Тогда это совпадения, где сумма равна количеству столбцов.

Например:

In []: A= arange(12).reshape(4, 3)
In []: A
Out[]: 
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])
In []: 3== (0== (A- [3, 4, 5])).sum(1)
Out[]: array([False,  True, False, False], dtype=bool)

Обновление : на основе комментариев и других ответов:
Предложение Paul кажется действительно способным упростить код:

In []: ~np.all(A- [3, 4, 5], 1)
Out[]: array([False,  True, False, False], dtype=bool)
В ответе

JoshAdel в общих чертах подчеркивается проблема, связанная с 100% надежным определением равенства. Поэтому, очевидно, мой ответ действителен только в ситуациях, когда равенство может быть определено однозначно.

Обновление 2 : Но, как выяснил Emma, существуют угловые случаи, когда решение Paul не даст правильных результатов.

1 голос
/ 03 июля 2011

Это обобщение решения @ maz, которое обрабатывает поплавки более элегантно, где строгое равенство может потерпеть неудачу:

import numpy as np

def test_for_row(myarray,row):
    return any(np.allclose(row,x) for x in myarray)

Подробнее см. http://docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html.Также, как примечание, будьте осторожны, что вы не сделали что-то вроде from numpy import *, так как np.any и встроенный в Python any приведет к различным ответам, первый из которых будет неправильным.

0 голосов
/ 20 февраля 2015

Как насчет:

def row_in_array(myarray, myrow):
    return (myarray == myrow).all(-1).any()

Вот как это выглядит для ваших тестов:

myarray = numpy.array([[0,1],
                       [2,3],
                       [4,5]])

row_in_array(myarray, [2, 3])
# True
row_in_array(myarray, [2, 5])
# False
row_in_array(myarray, [0, 3])
# False
row_in_array(myarray, [6, 7])
# False
0 голосов
/ 23 января 2015

Я столкнулся с той же проблемой, и следующий подход работает для меня

def is_row_in_matrix(row, matrix):
    return sum(np.prod(matrix == row, axis = 1))

В основном, проверьте, находится ли каждый элемент строки в соответствующем столбце матрицы, затем умножьте вдоль столбца (axis = 1), и суммируем результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...