You are reducing the last axis on the two inputs Image
and P
. So, you can use np.tensordot
, like so -
np.tensordot(Image,P,axes=(-1,-1))
This can also be expressed as np.dot
with some reshaping before and after it, like so -
Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
One can also use np.einsum
for such a reduction operation, like so -
np.einsum('ijk,lk->ijl',Image,P)
For performance, being a solely reduction operation, with no axis-alignment requirement, dot-based
solutions would be faster for large arrays, but for small to decent size arrays, einsum
might be better.
Runtime test
Case #1 :
In [46]: # Inputs
...: Image = np.random.randint(0,255,(256,256,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [47]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 206 ms per loop
100 loops, best of 3: 3.28 ms per loop
100 loops, best of 3: 3.22 ms per loop
100 loops, best of 3: 3.06 ms per loop
Case #2 :
In [48]: # Inputs
...: Image = np.random.randint(0,255,(512,512,3))
...: P = np.random.randint(0,255,(3,3))
...:
In [49]: %timeit change_base(Image,P)
...: %timeit np.tensordot(Image,P,axes=(-1,-1))
...: %timeit Image.reshape(-1,3).dot(P.T).reshape(Image.shape[:2]+(-1,))
...: %timeit np.einsum('ijk,lk->ijl',Image,P)
...:
1 loops, best of 3: 845 ms per loop
100 loops, best of 3: 12.8 ms per loop
100 loops, best of 3: 12.7 ms per loop
100 loops, best of 3: 13.4 ms per loop