2013-11-20 2 views
4

У меня есть матрица в scipy. И я пытаюсь заменить его на 1, если он удовлетворяет определенному условию, и 0, если это не так.Проверка элементов в матрице в python

for a in range(0,l): 
     for b in range(0,l): 
       if Matrix[a][b] == value: 
        Matrix[a][b] = 1 
       else: 
        Matrix[a][b] = 0 

В моей матрице полно элементов, имеющих в себе «значение». Тем не менее, это дает мне результат как матрицу, которая полностью равна нулю.

Это сработало раньше по аналогичному сценарию. Может быть, это что-то со структурой матрицы?

Вот как матрица выглядит на first--

[ [0 1. 1. 2.] 
    [1. 0. 2. 1.] 
    [1. 2. 0. 1.] 
    [2. 1. 1. 0.]] 

Когда я установить == значение 1. Я получаю все 1 до 1, и все 2 до нуля. Это то, что я хочу.

Но, когда я установил значение == 2. Я получаю все до нуля.

, когда я делаю все, что было предложено.

[[ 0. 1. 1. 2. 1. 2. 2. 3.] 
[ 1. 0. 2. 1. 2. 1. 3. 2.] 
[ 1. 2. 0. 1. 2. 3. 1. 2.] 
[ 2. 1. 1. 0. 3. 2. 2. 1.] 
[ 1. 2. 2. 3. 0. 1. 1. 2.] 
[ 2. 1. 3. 2. 1. 0. 2. 1.] 
[ 2. 3. 1. 2. 1. 2. 0. 1.] 
[ 3. 2. 2. 1. 2. 1. 1. 0.]] 

>> np.where(matrix==2,1,0) 
>> array([[0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0]]) 
+0

Можете ли вы присвоить свою матрицу, чтобы мы могли помочь? –

+0

Какая ценность 'l'? – aIKid

+2

Стандартный протокол отладки: перед сравнением, которое не соответствует вашему мнению, распечатать все. 'print (a, b, repr (Матрица [a] [b]), тип (Матрица [a] [b]), repr (значение), тип (значение))'. Если матрица численная, вы также можете добавить 'print (Matrix [a] [b] -value]'. Вы либо увидите кучу результатов, которые будут полезны, либо вообще ничего не увидите, что скажет вам что-то еще. – DSM

ответ

5

Если у вас действительно есть матрица там, а не ndarray, то

Matrix[a] 

является матрица 1-рядный и 2D. Точно так же,

Matrix[a][b] 

также матрица (или IndexError, поскольку Matrix[a] имеет только 1 строку). Вам необходимо использовать

Matrix[a, b] 

, чтобы получить элементы. Это одна из причин, почему использование матриц может быть неудобным. Обратите внимание, что вы могли бы просто использовать

Matrix == value 

получить матрицу булевы, а затем использовать astype, чтобы преобразовать его в тип вы хотите. Это будет меньше кода, и он будет работать быстрее. Таким образом, если ваш DTYPE является int32, вся сдвинутая вещь, которую ты отправила можно заменить

return (Matrix == value).astype(numpy.int32) 

или, если вы действительно хотите изменить массив на месте, вы можете использовать numpy.equal ufunc с out параметром:

numpy.equal(Matrix, value, out=Matrix) 
+0

Зачем вам нужно делать Matrix [a, b]? Вы можете настроить 2d-массив, чтобы использовать Matrix [a] [b], используя матрицу, заполненную матрицами. Я не знал, что есть другой способ. – JFA

+1

@JFA: Поскольку одномерное индексирование матрицы создает матрицу.Таким образом, две последовательные операции индексирования 1D, как и в 'Matrix [a] [b]', также создают матрицу. Вы можете думать о ndarrays, которые работают так, как вы ожидали. – user2357112

+0

Я теряюсь в том, что вы говорите. Ваша последняя строка делает то, что именно? Я хочу, чтобы мой вывод был логическим (но в смысле 1 и 0, а не истинным или ложным). Кроме того, я не получаю никаких ошибок индекса от того, что я делал. –

0

Я не знаком с scipy, но если Matrix нормальный список, я хотел бы сделать это:

#Assuming l is the length of Matrix 
for a in range(l): 
     for b in range(len(Matrix[a])): 
       if Matrix[a][b] == value: 
        Matrix[a][b] = 1 
       else: 
        Matrix[a][b] = 0 

Вот небольшая демонстрация:

>>> Matrix = [[1,2], [3,4]] 
>>> value = 2 
>>> l = len(Matrix) 
>>> for a in range(l): 
     for b in range(len(Matrix[a])): 
       if Matrix[a][b] == value: 
        Matrix[a][b] = 1 
       else: 
        Matrix[a][b] = 0 


>>> Matrix 
[[0, 1], [0, 0]] 
+0

Это дает мне ошибку «Ожидаемый»: ', найденный' = '. –

+0

@NilesBernoulli: Вы, вероятно, напортачили. Как указано, этот ответ не имеет синтаксической ошибки (хотя он имеет логическую ошибку). – user2357112

+0

Спасибо, но это не работает. Пока он заменяет его только в том случае, если значение установлено = 1, но не для других значений (которые явно находятся в матрице). Я сделаю редактирование. Одна секунда. –

1

Вы можете использовать np.where, чтобы сделать это.

Дано:

>>> matrix 
array([[0, 1, 1, 2], 
     [1, 0, 2, 1], 
     [1, 2, 0, 1], 
     [2, 1, 1, 0]]) 

Это заменяет 2 значения в matrix с 0 и оставляет другие ценности в одиночку:

>>> np.where(matrix==2,0,matrix) 
array([[0, 1, 1, 0], 
     [1, 0, 0, 1], 
     [1, 0, 0, 1], 
     [0, 1, 1, 0]]) 

Или это заменяет 2 значения с 0 и любым другим значением с 1:

>>> np.where(matrix==2,0,1) 
array([[1, 1, 1, 0], 
     [1, 1, 0, 1], 
     [1, 0, 1, 1], 
     [0, 1, 1, 1]]) 

Даже:

>>> np.where(matrix==2,' a two','not two') 
array([['not two', 'not two', 'not two', ' a two'], 
     ['not two', 'not two', ' a two', 'not two'], 
     ['not two', ' a two', 'not two', 'not two'], 
     [' a two', 'not two', 'not two', 'not two']], 
     dtype='<U7') 
+0

np.where работает хорошо, чтобы найти значения, но когда я пытаюсь дать условие, где, если матрица! = 2, ситуация становится хаотичной. Значения матричного элемента имеют периоды после них. Это проблема? –

+0

Что такое dtype - массив? – dawg

+0

Посмотрите на новое редактирование. Im собирается опубликовать. Одна секунда. редактирование: есть. –

1

Я имею в виду, что это может быть из-за сравнения с плавающей точкой. Вы ищете value == 2, но, похоже, ваша матрица содержит значения с плавающей запятой. Вы уверены, что все ваши 2.0 в вашей матрице - это точно 2.0, а не 1.999999999 или что-то подобное?

Как в этом примере (из IPython-терминал)

In [35]: A = array([1.999999999, 1.999999999]) 

In [36]: A 
Out[36]: array([ 2., 2.]) 

In [37]: A == 2 
Out[37]: array([False, False], dtype=bool) 

Как вы можете видеть, даже если матрица А выглядит она содержит точное значение «2.0` это на самом деле не происходит, это просто он печатается.

Update: Предлагаемое изменение кода

Чтобы избежать этой проблемы можно использовать функцию numpy.isclose и просто заменить вашу зацикливание с

ok_mask = np.isclose(Matrix, value) 
fail_mask = ~ok_mask 
Matrix[ok_mask] = 1 
Matrix[fail_mask] = 0 

Я предполагаю, что это также имеет преимущество, вероятно, был немного быстрее, чем ваши текущие петли.

+0

+1. Этот тип неточности очень вероятен, когда значения были рассчитаны, а не заданы явно. Обычный способ заключается в том, чтобы вместо этого проверить, достаточно ли «близки» значения, которые зависят от точности исходных измерений, но, например, если ваши данные точны до двух знаков после запятой, вы можете сделать «np.abs» (массив - 2) <0,01'. – lvc

+0

Я думаю, что использование 'numpy.isclose', вероятно, лучше. Я уточню свой ответ. –

Смежные вопросы