# array_correspondence

## `array_correspondence(A, B, axis=None)`

Computes a map from A to the equal elements in B

Parameters:

Name Type Description Default
`A` `(a,) or (a,k) numpy array (must be 1-dim or 2-dim)`
required
`B` `(b,) or (b,k) numpy array (must be 1-dim or 2-dim)`
required
`axis` `int or None, optional (default None)`

If None, will treat A and B as flat arrays. If a number, will check for equality of the entire axis, in which case the dimension of A and B across that axis must be equal.

`None`

Returns:

Name Type Description
`f` `(a,) numpy int array`

index list mapping from A to B, with -1 if there is no matching entry. If b contains multiple eligible entries, return an arbitrary one. If there are no -1s, `b[f] == a`

Examples:

Example with simple array correspondence:

``````>>> A = np.array([1,7,2,7,9,3,7,0])
>>> B = np.array([7,7,3,2,7,8])
>>> f = gpy.array_correspondence(A, B)
>>> f
array([-1,  0,  3,  0, -1,  2,  0, -1])
``````

Example with row correspondence:

``````>>> A = np.array([[1,3],[5,2],[1,2],[5,2]])
>>> B = np.array([[1,2],[6,9],[5,2]])
>>> f = gpy.array_correspondence(A, B, axis=0)
>>> f
array([-1,  2,  0,  2])
``````
Source code in `src/gpytoolbox/array_correspondence.py`
 ``` 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73``` ``````def array_correspondence(A,B,axis=None): """Computes a map from A to the equal elements in B Parameters ---------- A : (a,) or (a,k) numpy array (must be 1-dim or 2-dim) B : (b,) or (b,k) numpy array (must be 1-dim or 2-dim) axis : int or None, optional (default None) If None, will treat A and B as flat arrays. If a number, will check for equality of the entire axis, in which case the dimension of A and B across that axis must be equal. Returns ------- f : (a,) numpy int array index list mapping from A to B, with -1 if there is no matching entry. If b contains multiple eligible entries, return an arbitrary one. If there are no -1s, `b[f] == a` Examples -------- Example with simple array correspondence: ```python >>> A = np.array([1,7,2,7,9,3,7,0]) >>> B = np.array([7,7,3,2,7,8]) >>> f = gpy.array_correspondence(A, B) >>> f array([-1, 0, 3, 0, -1, 2, 0, -1]) ``` Example with row correspondence: ```python >>> A = np.array([[1,3],[5,2],[1,2],[5,2]]) >>> B = np.array([[1,2],[6,9],[5,2]]) >>> f = gpy.array_correspondence(A, B, axis=0) >>> f array([-1, 2, 0, 2]) ``` """ if axis not in (None, 0, 1, -1, -2): raise Exception("Axis can only be None, 0, 1, -1, -2") if len(A.shape) > 2 or len(B.shape) > 2: raise Exception("Inputs A, B can only be up to 2 dimensional") if axis==1 or axis==-1: # np.unique behaves weird with axis==1... but we only work with # up to dim 2, so always simply use the axis==0 case. A = A.T B = B.T axis = 0 # While we have to keep track of duplicates in A (to map them to the # correct place), we do not care about duplicates in B # uB is deduplicated B. mapB allows us to map to the first occurence of each vector. # (contribution by Towaki Takikawa) uB, mapB = np.unique(B, return_index=True, axis=axis) # We concatenate uB with A. Any entries from A that get de-duped is a 'hit'. _, idx, inv = np.unique(np.concatenate((uB,A), axis=axis), return_index=True, return_inverse=True, axis=axis) # We don't care about the range of the output that is about uB- that was a decoy to # grill out the hits from A. imap = idx[inv[uB.shape[0]:]] imap[imap>=uB.shape[0]] = -1 f = np.where(imap<0, -1, mapB[imap]) return f ``````