假设我有一个形状为 (1,2,3,3)
的 4D 数组:
test = np.array([[[[11,27,33],[45,58,96],[77,85,93]],[[55,27,39],[46,51,62],[73,86,98]]]])
标准化/计算 2D 子集 z 分数的最有效方法是什么?例如,test[0][0]
如下所示:
array([[11, 27, 33],
[45, 58, 96],
[77, 85, 93]])
这里有 2 个维度,但我想计算这两个维度的平均值和标准差,并使用这些值来标准化这 2 个维度中的每个值。
我可以像这样手动完成:
(test[0][0] - np.mean(test[0][0]))/np.std(test[0][0])
哪个正确给出:
array([[-1.61593336, -1.06970236, -0.86486574],
[-0.45519249, -0.01137981, 1.2859188 ],
[ 0.63726949, 0.91038499, 1.18350049]])
但是,这需要我迭代 4D 数组的前 2 个维度,考虑到实际数据的大小,这将花费太长时间
我看到 scipy
有一个 zscore
函数,但一次只能在 1 维中工作:scipy.stats.zscore(test, axis=3 )
并且一直无法找到跨 2D 数组标准化的简单实现
最佳答案
方法#1:您可以使用 np.mean
和np.std
在多个轴上(在本例中是在最后两个轴上) axis=(2,3)
并保持其暗淡数量与 keepdims=1
相同以便后面的减法和除法运算是可广播的。
因此,矢量化实现将是 -
(test - test.mean(axis=(2,3),keepdims=1)) / test.std(axis=(2,3),keepdims=1)
方法#2:使用 std
定义的替代方法这将重新使用平均计算 -
m = (test - test.mean(axis=(2,3),keepdims=1))
s = np.sqrt((np.abs(m)**2).mean(axis=(2,3),keepdims=1))
out = m/s
方法#3:对于较大的数据集,您可能需要使用 numexpr
非常有效地执行求和/平均操作的模块 -
import numexpr as ne
d0,d1 = test.shape[-2:]
m = (test - test.mean(axis=(2,3),keepdims=1))
m1 = m.reshape(-1,d0*d1)
s = np.sqrt(ne.evaluate('sum(abs(m1)**2,1)')/(d0*d1))
out = m/s[:,None,None]
基于 this post
,我们可以替换那些 division by s
与 1.0/s
然后乘以 m
进一步提升性能。这适用于上述所有三种方法。
关于python - numpy 标准化 4D 数组的 2D 子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40956114/