我用numpy测试了就地操作的行为。我观察到以下内容:
test = np.arange(0, 10).reshape(2, 5)
mask = test > 5
这是
np.multiply(test, 3, out=test)
# Output:
[[ 0 3 6 9 12]
[15 18 21 24 27]]
但这
np.multiply(test[mask], 3, out=test[mask])
print(test)
# Output:
[[0 1 2 3 4]
[5 6 7 8 9]]
没有。为什么?
为便于比较,下面是一些测试:
面具中很少有真实值:
import numpy as np
test = np.arange(100000)
mask = test < 100
%timeit np.multiply(test, 3, out=test, where=mask)
# 6.98 µs ± 90.2 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit test[mask] *= 3
# 21.3 µs ± 159 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit test[mask] = test[mask] * 3
# 21.9 µs ± 214 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
有很多真实的价值观:
test = np.arange(100000)
mask = test < 90000
%timeit np.multiply(test, 3, out=test, where=mask)
# 60.9 µs ± 554 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit test[mask] *= 3
# 100 µs ± 474 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
%timeit test[mask] = test[mask] * 3
# 120 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
随机掩码:
test = np.arange(100000)
mask = np.random.choice([True, False], size=100000)
%timeit np.multiply(test, 3, out=test, where=mask)
# 411 µs ± 4.25 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit test[mask] *= 3
# 712 µs ± 7.93 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
%timeit test[mask] = test[mask] * 3
# 714 µs ± 5.72 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
为完整,不带掩码:
%timeit np.multiply(test, 3, out=test)
# 22.4 µs ± 126 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
所以我会推荐np.multiply
与out=arr
和where=mask
。