Реализация от MATLAB до Python без итераций

Предположим, у вас есть следующий код в MATLAB:

[xi yi imv] = find(imagee+0.1); imv = imv - 0.1; wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv'); 

И вы хотите реализовать этот код в Python. Imagee представляет собой предопределенное синтетическое изображение, представленное массивом 10×10 со значениями 0,1,2. Какой был бы самый эффективный метод достижения этого? Я знаю, что вы могли бы итеративно пройти через всю матрицу и изменить значения, как вы идете, но я уверен, что у python есть более быстрый метод, чем это.

EDIT: уточнить на imagee: (я уже перевел это на python)

  C= np.zeros((L,L), int) C[:L/2,:L/2]=1 C[L/2:L,:L/2]=2 

One Solution collect form web for “Реализация от MATLAB до Python без итераций”

Я вижу, вы уже используете numpy , что является шагом в правильном направлении. Теперь давайте рассмотрим каждое утверждение по одному за раз и получим numpy эквивалент того, что вам нужно. Он говорит, что ваша матрица 10 x 10 , и поэтому я собираюсь предположить, что L = 10 . Вот что мы начнем с (в IPython):

 In [2]: import numpy as np In [3]: L = 10 In [4]: C= np.zeros((L,L), int) In [5]: C[:L/2,:L/2]=1 In [6]: C[L/2:L,:L/2]=2 In [7]: C Out[7]: array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0], [2, 2, 2, 2, 2, 0, 0, 0, 0, 0]]) 

Теперь давайте пройдем каждую линию по одному.


 [xi yi imv] = find(imagee+0.1); 

imv основном дает вам вектор всех значений в imagee+0.1 , которые отличны от нуля. Однако вам нужно иметь в виду, что MATLAB вернет эти значения в основном порядке столбца , тогда как numpy будет выполнять ту же операцию в строчном порядке. Если вы хотите воспроизвести одно и то же поведение в Python, вам нужно сначала перенести матрицу. Таким образом, я создам новую матрицу, которая переносит imagee и добавляет 0,1 к каждой записи для удобства. Однако я немного смущен, потому что если imagee уже состоит из 0,1,2 , если вы добавите каждое значение в эту матрицу на 0,1, imv вернет все значения в imagee+0.1 …. и это кажется мне бессмысленным , Тем не менее, вы можете использовать numpy.nonzero чтобы numpy.nonzero места ненулевых элементов. Когда вы найдете эти ненулевые элементы, вы можете просто индексировать в транспозицию C добавленную с помощью 0.1 чтобы получить нужные значения. numpy.nonzero вернет кортеж из двух элементов, где первый элемент представляет собой массив, который сообщает вам расположение строк тех значений, которые были отличны от нуля в C+0.1 а второй элемент – это массив, который сообщает вам о местоположениях столбцов, которые были отличное от нуля в C+0.1 :

 In [9]: CT = CT + 0.1 In [10]: ind = CT.nonzero() In [11]: imv = CT[ind[0], ind[1]] In [12]: imv Out[12]: array([ 1.1, 1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 2.1, 1.1, 1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 2.1, 1.1, 1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 2.1, 1.1, 1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 2.1, 1.1, 1.1, 1.1, 1.1, 1.1, 2.1, 2.1, 2.1, 2.1, 2.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]) 

Если вы сделали ту же операцию в MATLAB, вы заметите, что imv в обоих Python и MATLAB дает тот же порядок значений.


 imv = imv - 0.1; 

Это легко:

 In [22]: imv = imv - 0.1 In [23]: imv Out[23]: array([ 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 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.]) 

 wv = abs(imv*ones(1,length(imv)) - ones(length(imv),1)*imv'); 

Первая часть этого утверждения (внутри вызова abs ) выполняет внешнее произведение двух векторов. В MATLAB, imv будет N x 1 , и вы умножаете это на 1 x N вектора из них. Вы можете использовать numpy.outer чтобы помочь вам выполнить этот шаг внешнего продукта. Обратите внимание, что для 1D массивов numpy не различает векторы строк и векторы столбцов, и поэтому умножение вектора с транспонированием другого, к сожалению, не даст вам того, чего вы ожидаете. Однако, если вам нужно это поведение, вы должны явно определить двумерную матрицу с одноэлементным размером 1 (либо строк, либо столбцов), но давайте отложим это для этой записи.

Вторая часть этого утверждения также выполняет внешний продукт, но на транспонированной версии первой части инструкции.

Следовательно:

 In [24]: ones_vector = np.ones(len(imv)) In [25]: wv = np.abs(np.outer(imv, ones_vector) - np.outer(ones_vector, imv)) In [26]: wv Out[26]: array([[ 0., 0., 0., ..., 1., 1., 1.], [ 0., 0., 0., ..., 1., 1., 1.], [ 0., 0., 0., ..., 1., 1., 1.], ..., [ 1., 1., 1., ..., 0., 0., 0.], [ 1., 1., 1., ..., 0., 0., 0.], [ 1., 1., 1., ..., 0., 0., 0.]]) 

Первая часть кода объявляет вектор для удобства. После этого мы вычисляем то, что вы желаете.


Надеюсь это поможет!

  • Есть ли преимущества использования интерфейса Python / C вместо Cython?
  • Есть ли функция Numpy, чтобы вернуть первый индекс чего-то в массиве?
  • повторное импортирование сглаженных / затененных встроенных методов python
  • Установка numpy из формата колеса: «... не поддерживается колесо на этой платформе»
  • Как пробовать массив numpy и эффективно выполнять вычисления по каждому образцу?
  • Python / Numpy: установка значений в диапазоны индексов
  • Что такое эквивалент python / numpy num2cell ()?
  • Индекс элемента в массиве Numpy
  • Python - лучший язык программирования в мире.