You can use (A[:,:,np.newaxis] == np.arange(A.max()+1)).astype(int) .
Here's a demo:
In [52]: A Out[52]: array([[2, 0, 0, 2], [3, 1, 2, 3], [3, 2, 1, 0]]) In [53]: B = (A[:,:,np.newaxis] == np.arange(A.max()+1)).astype(int) In [54]: B Out[54]: array([[[0, 0, 1, 0], [1, 0, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0]], [[0, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]])
Check out a few individual elements of A :
In [55]: A[0,0] Out[55]: 2 In [56]: B[0,0,:] Out[56]: array([0, 0, 1, 0]) In [57]: A[1,3] Out[57]: 3 In [58]: B[1,3,:] Out[58]: array([0, 0, 0, 1])
The expression A[:,:,np.newaxis] == np.arange(A.max()+1) uses broadcasting to compare each element of A with np.arange(A.max()+1) . For one value, it looks like this:
In [63]: 3 == np.arange(A.max()+1) Out[63]: array([False, False, False, True], dtype=bool) In [64]: (3 == np.arange(A.max()+1)).astype(int) Out[64]: array([0, 0, 0, 1])
A[:,:,np.newaxis] is a three-dimensional view of A with the form (3,4,1) . An additional size is added so that a comparison with np.arange(A.max()+1) will be passed to each element, giving a result with the form (3, 4, A.max()+1) .
With a trivial change, this will work for an n-dimensional array. Indexing a numpy array with an ellipsis ... means "all other dimensions." So
(A[..., np.newaxis] == np.arange(A.max()+1)).astype(int)
converts an n-dimensional array into an (n + 1) -dimensional array, where the last dimension is a binary indicator of an integer in A Here is an example with a one-dimensional array:
In [6]: a = np.array([3, 4, 0, 1]) In [7]: (a[...,np.newaxis] == np.arange(a.max()+1)).astype(int) Out[7]: array([[0, 0, 0, 1, 0], [0, 0, 0, 0, 1], [1, 0, 0, 0, 0], [0, 1, 0, 0, 0]])