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

Python Numpy:将每行除以一个向量元素,python,arrays,numpy,scipy,Python,Arrays,Numpy,Scipy,假设我有一个numpy数组: data = np.array([[1,1,1],[2,2,2],[3,3,3]]) 我有一个对应的“向量”: 如何沿每行对数据进行减法或除法运算,结果如下: sub_result = [[0,0,0], [0,0,0], [0,0,0]] div_result = [[1,1,1], [1,1,1], [1,1,1]] 长话短说:如何使用与每行对应的一维标量数组对二维数组的每一行执行操作?给你。您只需将None(或者np.newaxis)与广播结合使用即可:

假设我有一个numpy数组:

data = np.array([[1,1,1],[2,2,2],[3,3,3]])
我有一个对应的“向量”:

如何沿每行对
数据
进行减法或除法运算,结果如下:

sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,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]])
data:            3 x 3
vector:              3
vector reshaped: 3 x 1

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

(data.T - vector).T

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

有关广播的更详细说明,请参阅
JoshAdel的解决方案使用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]])
data:            3 x 3
vector:              3
vector reshaped: 3 x 1
请注意,
data/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]])

蟒蛇式的方法是

np.divide(data.T,vector).T
这需要重新塑造形状,并且结果是浮点格式的。 在其他答案中,结果采用舍入整数格式


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

添加到stackoverflowuser2010的答案中,在一般情况下,您可以使用

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

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

data / vector.reshape(-1,1)

这会将向量转换为
列矩阵/向量
。允许您按照自己的意愿执行元素操作。至少对我来说,这是最直观的方法,因为(在大多数情况下)numpy只会使用同一内存的视图进行重塑,这也是有效的。

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

[1]中的
:数据/向量。重塑(-1,1)
出[1]:
数组([[1,1,1.],
[1., 1., 1.],
[1., 1., 1.]])
[2]中:数据/向量。重塑(1,-1)
出[2]:
数组([[1,0.5,0.33333],
[2.        , 1.        , 0.66666667],
[3.        , 1.5       , 1.        ]])
类似的:

x=np.arange(9).重塑(3,3)
x
数组([[0,1,2],
[3, 4, 5],
[6, 7, 8]])
x/np.sum(x,axis=0,keepdims=True)
数组([[0,0.08333,0.1333333],
[0.33333333, 0.33333333, 0.33333333],
[0.66666667, 0.58333333, 0.53333333]])
x/np.sum(x,axis=1,keepdims=True)
数组([[0,0.33333333,0.66666 7],
[0.25      , 0.33333333, 0.41666667],
[0.28571429, 0.33333333, 0.38095238]])
打印(np.sum(x,轴=0.shape)
打印(np.sum(x,轴=1.shape)
打印(np.sum(x,axis=0,keepdims=True).shape)
打印(np.sum(x,轴=1,keepdims=True).shape)
(3,)
(3,)
(1, 3)
(3, 1)

是使用最新版本numpy(1.18.1)的doc.a@user108569,
None
仍然与
np.newaxis
等效。我不确定您的设置是什么,或者您遇到的确切问题,但答案仍然有效。注意:这不符合OP的要求。最终结果是数组([[1,0.5,0.33333333],[2,1,0.66666 7],[3,1.5,1.])。它可能是“蟒蛇式的”,但它是不正确的。@MarkCramer谢谢你。我已经更正了我的答案以提供正确的结果。这应该是可以接受的答案。使用
.reformate(-1,1)
创建列向量是使用广播最直观的方法。
data = np.array([[1,1,1],[2,2,2],[3,3,3]])

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

data / vector.reshape(-1,1)