I have a large numpy array:
array([[32, 32, 99, 9, 45], # A
[99, 45, 9, 45, 32],
[45, 45, 99, 99, 32],
[ 9, 9, 32, 45, 99]])
and a large-ish array of unique values in a particular order:
array([ 99, 32, 45, 9]) # B
How can I quickly (no python dictionaries, no copies of A
, no python loops) replace the values in A
so that become the indicies of the values in B
?:
array([[1, 1, 0, 3, 2],
[0, 2, 3, 2, 1],
[2, 2, 0, 0, 1],
[3, 3, 1, 2, 0]])
I feel reaaly dumb for not being able to do this off the top of my head, nor find it in the documentation. Easy points!
Here you go
A = array([[32, 32, 99, 9, 45], # A
[99, 45, 9, 45, 32],
[45, 45, 99, 99, 32],
[ 9, 9, 32, 45, 99]])
B = array([ 99, 32, 45, 9])
ii = np.argsort(B)
C = np.digitize(A.reshape(-1,),np.sort(B)) - 1
Originally I suggested:
D = np.choose(C,ii).reshape(A.shape)
But I realized that that had limitations when you went to larger arrays. Instead, borrowing from @unutbu's clever reply:
D = np.argsort(B)[C].reshape(A.shape)
Or the one-liner
np.argsort(B)[np.digitize(A.reshape(-1,),np.sort(B)) - 1].reshape(A.shape)
Which I found to be faster or slower than @unutbu's code depending on the size of the arrays under consideration and the number of unique values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With