是否有更有效的方法来切割多维数组

时间:2016-12-21 08:16:36

标签: python numpy

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

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

当我索引a1

%%timeit
a1[500000]
  

最慢的跑步比最快跑的时间长39.17倍。这可能意味着正在缓存中间结果。   10000000次循环,最佳3:每循环84.6 ns

%%timeit
a2[500, 0]
  

最慢的运行时间比最快的运行时间长31.85倍。这可能意味着正在缓存中间结果。   10000000次循环,最佳3:每循环102 ns

%%timeit
a3[50, 0, 0]
  

最慢的运行时间比最快的运行时间长46.72倍。这可能意味着正在缓存中间结果。   10000000次循环,最佳3:每循环119 ns

在什么时候我应该考虑一种索引或切片多维数组的替代方法?是什么情况使得值得努力和失去透明度?

1 个答案:

答案 0 :(得分:5)

切片(n, m)数组的另一种方法是展平数组并得出它的一维位置必须是什么。

考虑a = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
我们可以使用a[1, 2]获取第2行第3列并获取5
或者,如果我们用1 * a.shape[1] + 2展平a,我们可以计算order='C'是一维位置 因此我们可以使用a.ravel()[1 * a.shape[1] + 2]

执行等效切片

效率这么高吗?不,为了从数组索引单个数字,它不值得麻烦。

如果我们想从数组中切出许多数字呢?我为2-D阵列设计了以下测试

2-D测试

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

看来,当切片超过100,000个数字时,最好平整阵列。

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

类似的结果,可能更具戏剧性。

<强> 结论
对于二维数组,如果需要从数组中提取超过100,000个元素,请考虑展平并导出展平位置。

对于3个或更多维度,似乎很清楚扁平化阵列几乎总是更好。

欢迎批评
我做错什么了吗?我没有想到明显的东西吗?

相关问题