python - numpy 标准化 4D 数组的 2D 子集

标签 python arrays performance numpy vectorization

假设我有一个形状为 (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.meannp.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 s1.0/s然后乘以 m进一步提升性能。这适用于上述所有三种方法。

关于python - numpy 标准化 4D 数组的 2D 子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40956114/

相关文章:

java - Java 中有 JFrame 的有效替代品吗?

python - 具有浮点索引的二维矩阵的径向轮廓

python - 在vtk python api中绘制多个平面

Python Turtle.Terminator 即使在使用 exitonclick() 之后

java - 从文本文件创建二维数组

javascript - 为什么这个 JavaScript 函数被调用两次?

python - 删除字符串中的数字和所有连接字符

python - 使用 Sqlite3 的数据库

python - 计算滚动 x 骰子与 y 边的所有可能的总和

分层 Canvas 与手动drawImage()的性能