我目前正在学习 Numpy 中的广播,在我正在阅读的书中( Python for Data Analysis by Wes McKinney 作者提到了以下示例来“贬低”二维数组:
import numpy as np
arr = np.random.randn(4, 3)
print(arr.mean(0))
demeaned = arr - arr.mean(0)
print(demeaned)
print(demeand.mean(0))
这实际上导致数组demeaned
的平均值为0。
我想到将其应用于类似图像的三维数组:
import numpy as np
arr = np.random.randint(0, 256, (400,400,3))
demeaned = arr - arr.mean(2)
这当然失败了,因为根据广播规则,尾随尺寸必须匹配,但这里的情况并非如此:
print(arr.shape) # (400, 400, 3)
print(arr.mean(2).shape) # (400, 400)
现在,我已经通过从数组第三维中的每个索引中减去平均值来使其大部分工作:
demeaned = np.ones(arr.shape)
for i in range(3):
demeaned[...,i] = arr[...,i] - means
print(demeaned.mean(0))
此时,返回的值非常接近于零,我认为这是一个精度错误。我的这个想法真的是对的吗?还是还有其他我错过的警告?
此外,这并不是实现我想要实现的目标的最干净、最“numpy”的方式。是否有一个功能或原则可以用来改进代码?
最佳答案
从 numpy 版本 1.7.0 开始,np.mean
和其他几个函数在其 axis
参数中接受元组。这意味着您可以一次在图像的平面上执行操作:
m = arr.mean(axis=(0, 1))
该均值的形状为 (3,)
,图像的每个平面都有一个元素。
如果您想单独减去每个像素的平均值,您必须记住广播会在右边缘对齐形状元组。这意味着您需要插入一个额外的维度:
n = arr.mean(axis=2)
n = n.reshape(*n.shape, 1)
或者
n = arr.mean(axis=2)[..., None]
关于python - 从多维 Numpy 数组中减去平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59093981/