1 回答
TA贡献1784条经验 获得超7个赞
我会做这样的事情:
def updown(x):
result = np.zeros_like(x)
for i in range(len(x)):
mid = (len(x)+1)//2
a = x[:mid].mean(axis=0)
b = x[-mid:].mean(axis=0)
mask_a = a != 0
mask_b = (a == 0) & (b != 0)
result[i, mask_a] = (b[mask_a] - a[mask_a]) / abs(a[mask_a])
result[i, mask_b] = (b[mask_b] - a[mask_b]) / abs((a[mask_b] + b[mask_b])/2)
x = x[1:]
return result
在循环相当不可避免的情况下,最好预先分配结果数组(如果事先知道维度)并填充循环中的值。这还具有允许预先填充默认值零的优点。
无需在 列上应用任何内容,因为其他运算(和算术)可以很容易地应用于所选轴。xmean
条件逻辑是通过屏蔽实现的。
您还可以使用 和 关键字参数:outwherenp.divide
def updown(x):
result = np.zeros_like(x)
for i in range(len(x)):
mid = (len(x)+1)//2
a = x[:mid].mean(axis=0)
b = x[-mid:].mean(axis=0)
np.divide(b - a, abs(a), out=result[i], where=(a != 0))
np.divide(b - a, abs((a + b)/2), out=result[i], where=(a == 0) & (b != 0))
x = x[1:]
return result
让我们看看一些性能比较(我已经将整个原始代码包装在一个名为updown_orig)
对于维度,我们只看到 2 倍的改进:(20, 5)
In []: %timeit updown_orig(np.random.rand(20, 5))
1 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In []: %timeit updown(np.random.rand(20, 5))
508 µs ± 10.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
让我们将两个维度缩放 10(将 大小增加 100 倍):x
In []: %timeit updown_orig(np.random.rand(200, 50))
96.4 ms ± 1.91 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In []: %timeit updown(np.random.rand(200, 50))
5.84 ms ± 64 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
现在,差异约为16.5倍。
添加回答
举报