有没有更有效的方法来切片多维数组

2024-04-26 22:52:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我注意到索引多维数组比索引一维数组需要更多的时间

a1 = np.arange(1000000)
a2 = np.arange(1000000).reshape(1000, 1000)
a3 = np.arange(1000000).reshape(100, 100, 100)

当我索引a1

%%timeit
a1[500000]

The slowest run took 39.17 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 84.6 ns per loop

%%timeit
a2[500, 0]

The slowest run took 31.85 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 102 ns per loop

%%timeit
a3[50, 0, 0]

The slowest run took 46.72 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 119 ns per loop


我应该在什么时候考虑索引或切片多维数组的替代方法?在什么情况下值得付出努力并失去透明度?你知道吗


Tags: theruna1np数组thisthantimes
1条回答
网友
1楼 · 发布于 2024-04-26 22:52:47

(n, m)数组进行切片的另一种方法是将数组展平并导出它的一维位置。你知道吗

考虑a = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
我们可以用a[1, 2]得到第二行第三列,然后得到5
或者如果我们用order='C'
因此,我们可以使用a.ravel()[1 * a.shape[1] + 2]执行等效切片

这有效率吗?不,对于从数组中索引单个数字来说,不值得这么麻烦。你知道吗

如果我们想从数组中分割许多数字呢?我为二维阵列设计了以下测试


二维测试

from timeit import timeit

n, m = 10000, 10000
a = np.random.rand(n, m)
r = pd.DataFrame(index=np.power(10, np.arange(7)), columns=['Multi', 'Flat'])

for k in r.index:
    b = np.random.randint(n, size=k)
    c = np.random.randint(m, size=k)
    kw = dict(setup='from __main__ import a, b, c', number=100)
    r.loc[k, 'Multi'] = timeit('a[b, c]', **kw)
    r.loc[k, 'Flat'] = timeit('a.ravel()[b * a.shape[1] + c]', **kw)

r.div(r.sum(1), 0).plot.bar()

enter image description here

似乎在切片100000个以上的数字时,最好将数组展平。你知道吗


3-D
呢 三维测试

from timeit import timeit

l, n, m = 1000, 1000, 1000
a = np.random.rand(l, n, m)
r = pd.DataFrame(index=np.power(10, np.arange(7)), columns=['Multi', 'Flat'])

for k in r.index:
    b = np.random.randint(l, size=k)
    c = np.random.randint(m, size=k)
    d = np.random.randint(n, size=k)

    kw = dict(setup='from __main__ import a, b, c, d', number=100)
    r.loc[k, 'Multi'] = timeit('a[b, c, d]', **kw)
    r.loc[k, 'Flat'] = timeit('a.ravel()[b * a.shape[1] * a.shape[2] + c * a.shape[1] + d]', **kw)

r.div(r.sum(1), 0).plot.bar()

enter image description here

类似的结果,也许更具戏剧性。你知道吗

结论 对于二维数组,如果需要从数组中提取超过100000个元素,请考虑展平并导出展平位置。你知道吗

对于3维或3维以上的情况,很明显,展平阵列几乎总是更好的。你知道吗


欢迎批评 我做错什么了吗?我没想到什么明显的事吗?你知道吗

相关问题 更多 >