numpy:将每行除以一个向量元素


119

假设我有一个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标量数组在2D数组的每一行上执行操作?

Answers:


181

干得好。您只需要与广播结合使用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]])

13
是文档。
sazary 2015年


@ user108569使用最新版本的numpy(1.18.1),None仍然等效于np.newaxis。我不确定您的设置是什么,或者您遇到的确切问题,但是答案仍然有效。
JoshAdel

11

正如已经提到,切片用None或者np.newaxes是一个伟大的方式来做到这一点。另一种选择是使用转置和广播,如

(data.T - vector).T

(data.T / vector).T

对于高维数组,您可能需要使用swapaxesNumPy数组或NumPy的方法rollaxis函数。确实有很多方法可以做到这一点。

有关广播的完整说明,请参见 http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html


4

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。如果您明确将其重塑vector1x3而不是,则会得到此结果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]])

2

Pythonic的方法是...

np.divide(data.T,vector).T

这需要重整形,并且结果为浮点格式。在其他答案中,结果为四舍五入的整数格式。

#注意:数据和向量中的列数均应匹配


注意:这不符合OP的要求。最终结果是array([[1。,0.5,0.33333333],[2.,1.,0.66666667],[3.,1.5,1.]])。可能是“ Pythonic”,但不正确。
Mark Cramer

1
@MarkCramer谢谢。我已更正答案,以提供正确的结果。
shantanu pathak

1

在一般情况下,您可以使用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只会使用同一内部存储器的视图来重塑它的效率。


这应该是公认的答案。使用创建列向量.reshape(-1,1) 是使用广播的最直观方法。
Paul Rougieux
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.