问题: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标量数组在2D数组的每一行上执行操作?
Suppose I have a numpy array:
data = np.array([[1,1,1],[2,2,2],[3,3,3]])
and I have a corresponding “vector:”
vector = np.array([1,2,3])
How do I operate on data
along each row to either subtract or divide so the result is:
sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,1]]
Long story short: How do I perform an operation on each row of a 2D array with a 1D array of scalars that correspond to each row?
回答 0
干得好。您只需要与广播结合使用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]])
Here you go. You just need to use None
(or alternatively np.newaxis
) combined with broadcasting:
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]])
回答 1
As has been mentioned, slicing with None
or with np.newaxes
is a great way to do this.
Another alternative is to use transposes and broadcasting, as in
(data.T - vector).T
and
(data.T / vector).T
For higher dimensional arrays you may want to use the swapaxes
method of NumPy arrays or the NumPy rollaxis
function.
There really are a lot of ways to do this.
For a fuller explanation of broadcasting, see
http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
回答 2
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]])
JoshAdel’s solution uses np.newaxis to add a dimension. An alternative is to use reshape() to align the dimensions in preparation for broadcasting.
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]])
Performing the reshape() allows the dimensions to line up for broadcasting:
data: 3 x 3
vector: 3
vector reshaped: 3 x 1
Note that data/vector
is ok, but it doesn’t get you the answer that you want. It divides each column of array
(instead of each row) by each corresponding element of vector
. It’s what you would get if you explicitly reshaped vector
to be 1x3
instead of 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]])
回答 3
Pythonic的方法是…
np.divide(data.T,vector).T
这需要重整形,并且结果为浮点格式。在其他答案中,结果为四舍五入的整数格式。
#注意:数据和向量中的列数均应匹配
Pythonic way to do this is …
np.divide(data.T,vector).T
This takes care of reshaping and also the results are in floating point format.
In other answers results are in rounded integer format.
#NOTE: No of columns in both data and vector should match
回答 4
在一般情况下,您可以使用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只会使用同一内部存储器的视图来重塑它的效率。
Adding to the answer of stackoverflowuser2010, in the general case you can just use
data = np.array([[1,1,1],[2,2,2],[3,3,3]])
vector = np.array([1,2,3])
data / vector.reshape(-1,1)
This will turn your vector into a column matrix/vector
. Allowing you to do the elementwise operations as you wish. At least to me, this is the most intuitive way going about it and since (in most cases) numpy will just use a view of the same internal memory for the reshaping it’s efficient too.