python - Numpy: Multidimensional index. Row by row with no loop -
i have nx2x2x2 array called a. have nx2 array called b, tells me position of last 2 dimensions of in interested. getting nx2 array, either using loop (as in c in code below) or using list comprehension (as in d in code below). want know whether there time gains vectorization, and, if so, how vectorize task.
my current approach vectorization (e in code below), using b index each submatrix of a, not return want. want e return same c or d.
input:
a=np.reshape(np.arange(0,32),(4,2,2,2)) print("a") print(a) b=np.concatenate((np.array([0,1,0,1])[:,np.newaxis],np.array([1,1,0,0])[:,np.newaxis]),axis=1) print("b") print(b) c=np.empty(shape=(4,2)) n in range(0, 4): c[n,:]=a[n,:,b[n,0],b[n,1]] print("c") print(c) d = np.array([a[n,:,b[n,0],b[n,1]] n in range(0, 4)]) print("d") print(d) e=a[:,:,b[:,0],b[:,1]] print("e") print(e)
output:
a [[[[ 0 1] [ 2 3]] [[ 4 5] [ 6 7]]] [[[ 8 9] [10 11]] [[12 13] [14 15]]] [[[16 17] [18 19]] [[20 21] [22 23]]] [[[24 25] [26 27]] [[28 29] [30 31]]]] b [[0 1] [1 1] [0 0] [1 0]] c [[ 1. 5.] [ 11. 15.] [ 16. 20.] [ 26. 30.]] d [[ 1 5] [11 15] [16 20] [26 30]] e [[[ 1 3 0 2] [ 5 7 4 6]] [[ 9 11 8 10] [13 15 12 14]] [[17 19 16 18] [21 23 20 22]] [[25 27 24 26] [29 31 28 30]]]
the complicated slicing operation done in vectorized manner -
shp = a.shape out = a.reshape(shp[0],shp[1],-1)[np.arange(shp[0]),:,b[:,0]*shp[3] + b[:,1]]
you using first , second columns of b
index third , fourth dimensions of input 4d array, a
. means is, slicing 4d array, last 2 dimensions being fused together. so, need linear indices fused format using b
. of course, before doing that, need reshape a
3d array a.reshape(shp[0],shp[1],-1)
.
verify results generic 4d
array case -
in [104]: = np.random.rand(6,3,4,5) ...: b = np.concatenate((np.random.randint(0,4,(6,1)),np.random.randint(0,5,(6,1))),1) ...: in [105]: c=np.empty(shape=(6,3)) ...: n in range(0, 6): ...: c[n,:]=a[n,:,b[n,0],b[n,1]] ...: in [106]: shp = a.shape ...: out = a.reshape(shp[0],shp[1],-1)[np.arange(shp[0]),:,b[:,0]*shp[3] + b[:,1]] ...: in [107]: np.allclose(c,out) out[107]: true
Comments
Post a Comment