Is 2-dimensional numpy.take fast?

自闭症网瘾萝莉.ら 提交于 2019-12-01 13:20:39

The indexed version might be cleaned up with slice objects like this:

T[0:nx-2,1:ny-1] + T[2:nx,1:ny-1] + T[1:nx-1,0:ny-2]  + T[1:nx-1,2:ny] - 4.0 * T[1:nx-1,1:ny-1]

sy1 = slice(1,ny-1)
sx1 = slice(1,nx-1)
sy2 = slice(2,ny)
sy_2 = slice(0,ny-2)
T[0:nx-2,sy1] + T[2:nx,sy1] + T[sx1,xy_2]  + T[sx1,sy2] - 4.0 * T[sx1,sy1]

Thanks @Divakar and @hpaulj ! Yes, working with slice is viable too. Comparing all 4 approaches gives:

  1. fastest ex aequo: t(usual np) and t(slice)
  2. t(take) = 2 * t(slice)
  3. t(ix_) = 3 * t(slice)

Here the code and the results:

import numpy as np
from numpy import ix_ as r
nx = 500;    ny = 500
T = np.arange(nx*ny).reshape(nx, ny)

ix = np.arange(1,nx-1); 
iy = np.arange(1,ny-1);

jx = slice(1,nx-1); jxm = slice(0,nx-2); jxp = slice(2,nx)
jy = slice(1,ny-1); jym = slice(0,ny-2); jyp = slice(2,ny)

#------------------------------------------------------------
def p(U,kx,ky):
    return np.take(np.take(U,kx, axis=0), ky,axis=1)
#------------------------------------------------------------

%timeit ΔT_slice= -T[jxm,jy]     + T[jxp,jy]     - T[jx,jym]     + T[jx,jyp]     - 0.0 * T[jx,jy]
%timeit ΔT_npy  = -T[0:nx-2,1:ny-1] + T[2:nx,1:ny-1] - T[1:nx-1,0:ny-2]  + T[1:nx-1,2:ny] - 0.0 * T[1:nx-1,1:ny-1]
%timeit ΔT_take = -p(T,ix-1,iy)  + p(T,ix+1,iy)  - p(T,ix,iy-1)  + p(T,ix,iy+1)  - 0.0 * p(T,ix,iy)
%timeit ΔT_ix_  = -T[r(ix-1,iy)] + T[r(ix+1,iy)] - T[r(ix,iy-1)] + T[r(ix,iy+1)] - 0.0 * T[r(ix,iy)]
.
100 loops, best of 3: 3.14 ms per loop
100 loops, best of 3: 3.13 ms per loop
100 loops, best of 3: 7.03 ms per loop
100 loops, best of 3: 9.58 ms per loop

Concerning the discussion about view and copy the following might be instructive:

print("if False --> a view ;   if True --> a copy"  )
print("_slice_ :", T[jx,jy].base is None)
print("_npy_   :", T[1:nx-1,1:ny-1].base is None)
print("_take_  :", p(T,ix,iy).base is None)
print("_ix_    :", T[r(ix,iy)].base is None)
.
if False --> a view ;   if True --> a copy
_slice_ : False
_npy_   : False
_take_  : True
_ix_    : True
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!