Подтвердить что ты не робот

Numpy: разделите каждую строку на векторный элемент

Предположим, что у меня есть массив numpy:

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

и у меня есть соответствующий "вектор:"

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

Как я могу работать с data вдоль каждой строки, чтобы вычесть или разделить так, чтобы результат:

sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,1]]

Короче говоря: как выполнить операцию над каждой строкой двумерного массива с 1D массивом скаляров, который соответствует каждой строке?

4b9b3361

Ответ 1

Здесь вы идете. Вам просто нужно использовать None (или альтернативно np.newaxis) в сочетании с трансляцией:

In [6]: data - vector[:,None]
Out[6]:
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])

In [7]: data / vector[:,None]
Out[7]:
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

Ответ 2

Как уже упоминалось, нарезка с помощью None или с np.newaxes - отличный способ сделать это. Другой альтернативой является использование транспонирования и трансляции, как в

(data.T - vector).T

и

(data.T / vector).T

Для массивов с более высокой размерностью вы можете использовать метод swapaxes для массивов NumPy или функцию NumPy rollaxis. Существует действительно много способов сделать это.

Для более полного объяснения вещания см. http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

Ответ 3

В решении JoshAdel для добавления измерения используется np.newaxis. Альтернативой является использование reshape() для выравнивания размеров при подготовке к трансляции.

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

data
# array([[1, 1, 1],
#        [2, 2, 2],
#        [3, 3, 3]])
vector
# array([1, 2, 3])

data.shape
# (3, 3)
vector.shape
# (3,)

data / vector.reshape((3,1))
# array([[1, 1, 1],
#        [1, 1, 1],
#        [1, 1, 1]])

Выполнение функции reshape() позволяет объединить размеры для трансляции:

data:            3 x 3
vector:              3
vector reshaped: 3 x 1

Обратите внимание, что data/vector в порядке, но он не дает вам ответ, который вы хотите. Он разбивает каждый столбец array (вместо каждой строки) на каждый соответствующий элемент vector. Это то, что вы получили бы, если бы я явно переформатировал vector как 1x3 вместо 3x1.

data / vector
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])
data / vector.reshape((1,3))
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])

Ответ 4

Pythonic способ сделать это...

np.divide(data,vector)

Это позволяет изменить форму, а также результаты в формате с плавающей запятой. В других ответах результаты представлены в округленном целочисленном формате.

# ПРИМЕЧАНИЕ: количество столбцов в данных и векторе не должно совпадать

Ответ 5

Добавляя к ответу stackoverflowuser2010, в общем случае вы можете просто использовать

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

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

data / vector.reshape(-1,1)

Это превратит ваш вектор в column matrix/vector. Позволяет вам выполнять поэлементные операции, как вы хотите. По крайней мере, для меня это наиболее интуитивный способ, и (в большинстве случаев) numpy будет использовать только ту же внутреннюю память для эффективного преобразования.