160

假设我有一个 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]]

长话短说:如何使用与每一行对应的一维标量数组对二维数组的每一行执行操作?

4

6 回答 6

230

干得好。您只需要使用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]])
于 2013-10-26T02:38:15.733 回答
15

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

(data.T - vector).T

(data.T / vector).T

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

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

于 2013-10-26T04:10:05.223 回答
6

Pythonic 的方法是......

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

这负责重塑,结果也是浮点格式。在其他答案中,结果采用舍入整数格式。

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

于 2019-03-21T04:52:21.807 回答
6

添加到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 只会使用相同内部存储器的视图来重塑它也是有效的。

于 2019-07-10T11:35:42.807 回答
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。如果您明确地将其重塑vector为is1x3而不是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]])
于 2016-09-08T22:38:11.123 回答
1

关键是将大小为 (3,) 的向量重塑为 (3,1):将每一行除以一个元素或 (1,3):将每一列除以一个元素。由于 data.shape 不对应于 vector.shape,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)
于 2021-03-01T11:45:46.990 回答