Вставка значений в массив Numpy на основе значений в этом массиве - PullRequest
0 голосов
/ 07 июня 2018

Если у меня есть массив:

a = np.array([[1,2,3]])

Я могу добавить значение в этот массив на основе значений внутри массива.

a = np.insert(a,3,(0.299+a[0][1]*0.587+a[0][2]*0.114))

Это даст мне следующий массив.

array([1, 2, 3, 1.815])

Пока все хорошо.Но теперь я хочу сделать это для массива со следующей формой.

a = np.array(
    [
        [[1,2,3],[3,4,5]],
        [[6,7,8],[9,10,11]]
    ])

array([[[ 1,  2,  3],
        [ 3,  4,  5]],

       [[ 6,  7,  8],
        [ 9, 10, 11]]])

Есть ли способ сделать это без использования цикла for?

EDIT У исходного вопроса есть «минимальный рабочий пример», который был слишком упрощен, что привело к использованию функции np.sum ().Теперь следует следующая формула, которая мне нужна (0,299 * R + 0,587 * G + 0,114 * B)

Ответы [ 3 ]

0 голосов
/ 07 июня 2018

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

Надеемся, что следующее приблизит вас к реальному приложению на шаг:

#Define a function to apply to the matrix
def f(x, ar):
    return np.append(next(ar),x[0]*0.299+x[1]*0.587+x[2]*0.114)

#Create an iterator for semi-efficient stepping through the matrix elements
b = iter(a.reshape((a.shape[0]*a.shape[1],-1)))

#create output array; syntax:
#np.apply_along_axis(1D-function,axis_to_apply_along,object_to_apply_to,optional_arguments)
vals = np.apply_along_axis(f,2,a,b)

#vals
#Out[440]: 
#array([[[  1.   ,   2.   ,   3.   ,   1.815],
#        [  3.   ,   4.   ,   5.   ,   3.815]],
#
#       [[  6.   ,   7.   ,   8.   ,   6.815],
#        [  9.   ,  10.   ,  11.   ,   9.815]]])

Однако вызовы цикла for iter() в цикле to-loop-over последовательность и использует next() вызовы на результат.Таким образом, вышеуказанные функциональные возможности в основном реализуют цикл for альтернативным способом.Мы надеемся, что теперь единственное, что мы изменили, - это то, что мы избегаем зацикливания на неправильных вещах, поэтому экономим некоторое время в конце ..

0 голосов
/ 07 июня 2018

Вы можете попробовать:

a = np.array([[[1,2,3],[3,4,5]],[[6,7,8],[9,10,11]]]).astype(np.float_)
a = np.concatenate((a, 0.299*a[:,:,0:1] + 0.587 * a[:,:,1:2] + 0.114*a[:,:,2:3]), axis = 2 )

Это дает мне:

array([[[  1.   ,   2.   ,   3.   ,   1.815],
        [  3.   ,   4.   ,   5.   ,   3.815]],
       [[  6.   ,   7.   ,   8.   ,   6.815],
        [  9.   ,  10.   ,  11.   ,   9.815]]])

Примечание: Если вам нужна одинарная точность, используйте np.float32 вместо np.float_, что действительно соответствует двойной точности ( ссылка для типов numpy здесь ).И, конечно, если a уже имеет правильный тип, преобразование не требуется.

0 голосов
/ 07 июня 2018

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

a = np.insert(a, 3, a.sum(axis=-1), axis=-1)
a
#[[[ 1  2  3  6]
#  [ 3  4  5 12]]
#
# [[ 6  7  8 21]
#  [ 9 10 11 30]]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...