How to one-hot-encode an two dimensional matrix?

Viewed 563

I have a huge numpy 2d array, each value is a category between 0 and 3:

[[3 1 0 ... 1]
...
 [2 0 1 ... 3]]

I want to one-hot-encode it (0 is 0 0 0 1, 1 is 0 0 1 0, etc), so the above will become:

[[1 0 0 0 0 0 1 0 0 0 0 1 ... 0 0 1 0]
...
 [0 1 0 0 0 0 0 1 0 0 1 0 ... 1 0 0 0]]

What will be the most efficient way to do that? Thanks!

1 Answers

Let's say you have an (M, N) matrix, and your max value is P (= 4):

M = 6
N = 5
P = 4
mat = np.random.randint(P, size=(M, N))

First encode it as an (M, N, P) matrix of zeros and ones, using mat as the index in the last dimension:

encoded = np.zeros((M, N, P), dtype=int)
encoded[(*np.ogrid[:M, :N], (P - 1) - mat)]

Alternatively, use np.put_along_axis:

np.put_along_axis(encoded, (P - 1) - np.expand_dims(mat, -1), 1, axis=-1)

The data has the same order you want in memory already because numpy uses C order by default. You can just reshape to get the final result:

encoded.reshape(M, N * P)
Related