从多维 Numpy 数组中减去均值
Subtract Mean from Multidimensional Numpy-Array
我目前正在学习 Numpy 中的广播和正在阅读的书中(Python for Data Analysis by Wes McKinney 作者提到了以下示例 "demean" 二维数组:
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]
np.apply_along_axis(lambda x: x - np.mean(x), 2, arr)
输出:你得到相同形状的数组,其中每个单元格在你想要的维度上被贬低(第二个参数,这里是2)。
我目前正在学习 Numpy 中的广播和正在阅读的书中(Python for Data Analysis by Wes McKinney 作者提到了以下示例 "demean" 二维数组:
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]
np.apply_along_axis(lambda x: x - np.mean(x), 2, arr)
输出:你得到相同形状的数组,其中每个单元格在你想要的维度上被贬低(第二个参数,这里是2)。