Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy Lookup (Map, or Point)

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!

like image 735
Paul Avatar asked Feb 18 '11 01:02

Paul


1 Answers

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.

like image 105
JoshAdel Avatar answered Oct 11 '22 04:10

JoshAdel