Issue
I have two numpy arrays. A 3D or 2D array reference
and a 3D array map_
.
In this example let Reference be
reference = array([[ [11,12,13], [14,15,16], [17,18,19] ],
[ [21,22,23], [24,25,26], [27,28,29] ],
[ [31,32,33], [34,35,36], [37,38,39] ],
[ [41,42,43], [44,45,46], [47,48,49] ]])
An let map be
map_ = array([[ [0,0], [1,2], [2,2] ],
[ [2,1], [3,2], [3,0] ]])
The result should be
array([[ [11,12,13], [27,28,29], [37,38,39] ],
[ [24,25,36], [47,48,49], [41,42,43] ]])
I can solve it as:
array([[reference[i[0],i[1],:] for i in j] for j in map_])
However when map_ and reference are arrays of thousands by thousands, this become very slow.
Is there a fastest way to achieve this?
Solution
Just use advanced indexing:
result = reference[map[:,:,0], map[:,:,1]]
(BTW refrain from using keyword map
as variable name...)
Timing:
import timeit
%timeit test = np.array([[reference[i[0],i[1],:] for i in j] for j in mp])
# 4.53 µs ± 72.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
%timeit test = reference[mp[:,:,0], mp[:,:,1]]
# 1.64 µs ± 4.13 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
The gain will likely be more substantial on larger arrays... E.g. with map = np.random.randint(0,3,size=(100,100,2))
we get
4.11 ms ± 15.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
v.s.
98.5 µs ± 200 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
Answered By - Julien
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.