我想用列的平均值减去numpy数组中的所有值。
之前,以下代码有效:
centered_data = data - data.mean(axis = 1)
现在,此代码会生成如下错误消息:
ValueError:操作数无法与形状(3,862)(3,)
一起广播
将此行更改为:
centered_data = data - data.mean(axis = 1).reshape(data.shape[0],1)
数据类型为numpy.ndarray。
为什么平均向量现在需要重塑,而之前没有?
答案 0 :(得分:2)
data #has shape (3,862)
mean = data.mean(axis=1) #has shape (3,)
根据第一个广播规则:
在两个阵列上操作时,NumPy会比较它们的形状 逐元素。它从尾随尺寸开始,并起作用 前进的方向。
时兼容两个维度他们是平等的,或者其中一个是1
因此将3与862进行比较失败。因此,您需要将数据重塑为(862,3)或意味着(3,1)。
答案 1 :(得分:2)
np.mean
有一个keepdims
参数。 (data.mean
也有它,但它记录在np.mean
)中:
In [642]: data=np.arange(12).reshape(3,4)
In [643]: data.mean(axis=1, keepdims=True)
Out[643]:
array([[ 1.5],
[ 5.5],
[ 9.5]])
In [644]: data-data.mean(axis=1, keepdims=True)
Out[644]:
array([[-1.5, -0.5, 0.5, 1.5],
[-1.5, -0.5, 0.5, 1.5],
[-1.5, -0.5, 0.5, 1.5]])
如果不这样,mean
和sum
等操作会移除维度。 reshape(-1,1)
和[:,None]
也可以重新添加维度。
如果您在另一个轴上取平均值,则不需要保留(或恢复)尺寸。这是因为广播规则会在需要时自动添加维度:
In [645]: data-data.mean(axis=0)
Out[645]:
array([[-4., -4., -4., -4.],
[ 0., 0., 0., 0.],
[ 4., 4., 4., 4.]])
你的'之前'像这样的情况 - 减少axis=0
?
我不知道numpy
中的任何更改会导致axis=1
案例没有某种重塑或保密。
如果data.shape==(3, 4)
data+np.array([1,1,1,1])
# data+np.array([1,1,1,1])[None,:] # automatic None
作品。
这会引发一个值错误:
data+np.array([1,1,1])
ValueError: operands could not be broadcast together with shapes (3,4) (3)
这有效:
data+np.array([1,1,1])[:,None]
答案 2 :(得分:0)
您还可以将轴添加到数组中,以便广播。
>>> a
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23]])
>>> m = a.mean(-1)
>>> a.shape, m.shape
((3, 8), (3,))
>>> a - m[:, np.newaxis]
array([[-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5],
[-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5],
[-3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5]])
>>>
>>> m[:, np.newaxis].shape
(3, 1)
>>>
答案 3 :(得分:0)
问:“为什么平均向量现在需要重塑?”。
A :因为NumPy无法在(n,m)
和(n,)
之间执行操作。要进行广播,NumPy会查找轴兼容性,1
与任何轴都兼容。
(3,862) -
(3,) # error
(3,1) # this works
(1,1) # this works
(,862) # error
(1,862) # works