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]]

长话短说: 我如何执行一个操作的每一行的2D 数组与标量的一维数组对应的每一行?

145505 次浏览

在这里,你只需要使用 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]])

如前所述,使用 Nonenp.newaxes进行切片是一种很好的方法。 另一种选择是使用转换和广播,如

(data.T - vector).T

还有

(data.T / vector).T

对于高维数组,您可能希望使用 NumPy 数组的 swapaxes方法或 NumPy rollaxis函数。 有很多方法可以做到这一点。

有关广播的更全面解释,请参见 Http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

JoshAdel 的解决方案使用 np.newaxis 来添加一个维度。

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]])

执行重塑()可以让尺寸排列起来进行广播:

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]])

蟒蛇式的方法是..。

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

这样就可以进行重新整形,而且结果是浮点格式的。 在其他答案中,结果是圆角整数格式。

注意: 数据和向量中没有匹配的列

添加 stackoverflow user2010的答案,在一般情况下,您可以只使用

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。允许您按照自己的意愿执行元素操作。至少对我来说,这是最直观的方法,因为(在大多数情况下)麻木将只是使用相同的内部记忆的视图来重塑它也是有效的。

关键是将 size (3,)的向量重塑为(3,1) : 将每一行除以一个元素,或者(1,3) : 将每一列除以一个元素。由于 data.form 与 vector.form 不对应,NumPy 会自动将 Vector 的形状扩展为(3,3)并执行元素方面的除法。

In[1]: data/vector.reshape(-1,1)
Out[1]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])


In[2]: data/vector.reshape(1,-1)
Out[2]:
array([[1.        , 0.5       , 0.33333333],
[2.        , 1.        , 0.66666667],
[3.        , 1.5       , 1.        ]])


相似:

x = np.arange(9).reshape(3,3)
x
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])


x/np.sum(x, axis=0, keepdims=True)
array([[0.        , 0.08333333, 0.13333333],
[0.33333333, 0.33333333, 0.33333333],
[0.66666667, 0.58333333, 0.53333333]])


x/np.sum(x, axis=1, keepdims=True)
array([[0.        , 0.33333333, 0.66666667],
[0.25      , 0.33333333, 0.41666667],
[0.28571429, 0.33333333, 0.38095238]])


print(np.sum(x, axis=0).shape)
print(np.sum(x, axis=1).shape)
print(np.sum(x, axis=0, keepdims=True).shape)
print(np.sum(x, axis=1, keepdims=True).shape)
(3,)
(3,)
(1, 3)
(3, 1)