拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 使用“,”对切片的numpy阵列进行广播比较比“][”慢得多

使用“,”对切片的numpy阵列进行广播比较比“][”慢得多

白鹭 - 2022-01-23 2087 0 0

我不确定为什么比较切片的 numpy 阵列使用,][. 例如:

start = time.time()
a = np.zeros((100,100))
for _ in range(1000000):
    a[1:99][1:99] == 1
print(time.time() - start)

start = time.time()
a = np.zeros((100,100))
for _ in range(1000000):
    a[1:99, 1:99] == 1
print(time.time() - start)
3.2756259441375732
11.044903039932251

差了 3 倍多。使用 的时间测量大致相同timeit

我正在研究递回算法(我打算这样做),这些问题使我的程序运行速度变慢,从大约 1 秒增加到 10 秒。我只想知道他们背后的原因。可能这是一个错误。我正在使用 Python 3.9.9。谢谢。

uj5u.com热心网友回复:

第一个与a[2:99]==1. 一个 (98,100) 切片后跟一个 (97,100),然后是 == 测验。

In [177]: timeit (a[1:99][1:99]==1)
8.51 μs ± 16.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [178]: timeit (a[1:99][1:99])
383 ns ± 5.73 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [179]: timeit (a[1:99])
208 ns ± 10.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

大部分时间是测验,而不是切片。

In [180]: a[1:99,1:99].shape
Out[180]: (98, 98)
In [181]: timeit a[1:99,1:99]==1
32.2 μs ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [182]: timeit a[1:99,1:99]
301 ns ± 3.61 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

同样,切片是计时的一小部分,但==测验速度要慢得多。在第一种情况下,我们选择了行的子集,因此测验在资料缓冲区的连续块上进行。在第二个中,我们选择行和列的子集。通过资料缓冲区的迭代更为复杂。

我们可以通过测验一段列与一段行来简化比较:

In [183]: timeit a[:,2:99]==1
32.3 μs ± 13.8 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [184]: timeit a[2:99,:]==1
8.58 μs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

作为进一步的测验,使用“F”顺序创建一个新阵列。现在“行”是慢切片

In [189]: b = np.array(a, order='F')
In [190]: timeit b[:,2:99]==1
8.83 μs ± 20.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [191]: timeit b[2:99,:]==1
32.8 μs ± 31.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

===

但是你为什么要比较这两个切片,一个是 (97,100) 阵列,另一个是 (98,98)。他们正在挑选a.

我想知道您是否真的打算测验连续的行、列切片,而不是两行切片。

In [193]: timeit (a[1:99][:,1:99]==1)
32.6 μs ± 92.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

仅比较切片,我们发现顺序切片更慢 - 只是一点点。

In [194]: timeit (a[1:99][:,1:99])
472 ns ± 3.76 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [195]: timeit (a[1:99,1:99])
306 ns ± 3.19 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *