Chr*_*per 8 python numpy python-3.x array-broadcasting
I have quite a simple scenario where I'd like to test whether both elements of a two-dimensional array are (separately) members of a larger array - for example:
full_array = np.array(['A','B','C','D','E','F'])
sub_arrays = np.array([['A','C','F'],
['B','C','E']])
np.isin(full_array, sub_arrays)
Run Code Online (Sandbox Code Playgroud)
This gives me a single dimension output:
array([ True, True, True, False, True, True])
Run Code Online (Sandbox Code Playgroud)
showing whether elements of full_array are present in either of the two sub-arrays. I'd like instead a two-dimensional array showing the same thing for each of the two elements in sub_arrays - so:
array([[ True, False, True, False, False, True],
[ False, True, True, False, True, False]])
Run Code Online (Sandbox Code Playgroud)
Hope that makes sense and any help gratefully received.
A simple one would be with broadcasting after extending one of the arrays and then any-reduction along the respective axis -
In [140]: (full_array==sub_arrays[...,None]).any(axis=1)
Out[140]:
array([[ True, False, True, False, False, True],
[False, True, True, False, True, False]])
Run Code Online (Sandbox Code Playgroud)
searchsortedSpecific case #1
With full_array being sorted and all elements from sub_arrays present at least somewhere in full_array, we can also use np.searchsorted -
idx = np.searchsorted(full_array, sub_arrays)
out = np.zeros((sub_arrays.shape[0],len(full_array)),dtype=bool)
np.put_along_axis(out, idx, 1, axis=1)
Run Code Online (Sandbox Code Playgroud)
Specific case #2
With full_array being sorted and if not all elements from sub_arrays are guaranteed to be present at least somewhere in full_array, we need one extra step -
idx = np.searchsorted(full_array, sub_arrays)
idx[idx==len(full_array)] = 0
out = np.zeros((sub_arrays.shape[0],len(full_array)),dtype=bool)
np.put_along_axis(out, idx, full_array[idx] == sub_arrays, axis=1)
Run Code Online (Sandbox Code Playgroud)
Generic case
For the truly generic case of full_array not necessarily being sorted, we need to use sorter arg with searchsorted -
def isin2D(full_array, sub_arrays):
out = np.zeros((sub_arrays.shape[0],len(full_array)),dtype=bool)
sidx = full_array.argsort()
idx = np.searchsorted(full_array, sub_arrays, sorter=sidx)
idx[idx==len(full_array)] = 0
idx0 = sidx[idx]
np.put_along_axis(out, idx0, full_array[idx0] == sub_arrays, axis=1)
return out
Run Code Online (Sandbox Code Playgroud)
Sample run -
In [214]: full_array
Out[214]: array(['E', 'F', 'A', 'B', 'D', 'C'], dtype='|S1')
In [215]: sub_arrays
Out[215]:
array([['Z', 'C', 'F'],
['B', 'C', 'E']], dtype='|S1')
In [216]: isin2D(full_array, sub_arrays)
Out[216]:
array([[False, True, False, False, False, True],
[ True, False, False, True, False, True]])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3896 次 |
| 最近记录: |