Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy标准化4D阵列的2D子集_Python_Arrays_Performance_Numpy_Vectorization - Fatal编程技术网

Python numpy标准化4D阵列的2D子集

Python numpy标准化4D阵列的2D子集,python,arrays,performance,numpy,vectorization,Python,Arrays,Performance,Numpy,Vectorization,假设我有一个4D数组,形状(1,2,3,3): 标准化/计算2D子集z分数的最有效方法是什么?例如,test[0][0]如下所示: array([[11, 27, 33], [45, 58, 96], [77, 85, 93]]) 这里有两个维度,但我想计算两个维度的平均值和标准偏差,并使用这些值来标准化这两个维度中的每个值 我可以像这样手动操作: array([[11, 27, 33], [45, 58, 96], [77, 85, 9

假设我有一个4D数组,形状
(1,2,3,3)

标准化/计算2D子集z分数的最有效方法是什么?例如,
test[0][0]
如下所示:

array([[11, 27, 33],
       [45, 58, 96],
       [77, 85, 93]])
这里有两个维度,但我想计算两个维度的平均值和标准偏差,并使用这些值来标准化这两个维度中的每个值

我可以像这样手动操作:

array([[11, 27, 33],
       [45, 58, 96],
       [77, 85, 93]])
(测试[0][0]-np.均值(测试[0][0]))/np.标准(测试[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
函数,但一次只能在一维中工作:
scipy.stats.zscore(test,axis=3)
,并且还没有找到一个简单的实现,可以在二维数组中标准化要在numpy中进行标准化,只需进行广播匹配即可

def normalize_nchw(inp):
    EPS = 1e-6
    means = np.mean(inp, axis=(2,3)).expand_dims(-1).expand_dims(-1)
    inp -= means
    vars = EPS + np.mean(inp*inp, axis=(2,3)).expand_dims(-1).expand_dims(-1)
    inp *= (1./np.sqrt(vars))
旁注:如果你是为CNN这样做的,一个更好的主意是使用批量标准化,它内置于许多框架中。

方法#1:你可以利用
np.mean
np.std
在多个轴上使用
轴=(2,3)
并保持DIM的数量与
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]

基于,我们可以用
1.0/s
代替
除以s
,然后再乘以
m
,以进一步提高性能。这将适用于上述三种方法。

test.std不是要第二次计算平均值吗?@Kh40tiK啊,你说得对!我尽量保持简单。