Использование numy .isin поэлементно - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть довольно простой сценарий, в котором я хотел бы проверить, являются ли оба элемента двумерного массива (отдельно) членами большего массива, например:

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)

Это дает мневывод одного измерения:

array([ True,  True,  True, False,  True,  True])

, показывающий, присутствуют ли элементы full_array в любом из двух вложенных массивов.Вместо этого я бы хотел двумерный массив, показывающий одно и то же для каждого из двух элементов в sub_arrays - так:

array([[ True,  False,  True, False,  False,  True],
       [ False, True,   True, False,  True,  False]])

Надеюсь, что имеет смысл, и любая помощь с благодарностью получена.

1 Ответ

0 голосов
/ 05 декабря 2018

Вещательный базируемый один

Простой будет с broadcasting после расширения одного из массивов и затем любого уменьшения по соответствующей оси -

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]])

При searchsorted

Особый случай # 1

При сортировке full_array все элементы из sub_arrays присутствуют, по крайней мере, где-то в full_array,мы также можем использовать 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)

Особый случай # 2

При сортировке full_array и если гарантированы не все элементы из sub_arraysчтобы присутствовать хотя бы где-то в full_array, нам нужен еще один дополнительный шаг -

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)

Общий случай

Для действительно общего случая full_array нетОбязательно отсортировав, нам нужно использовать sorter arg с 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

Пример выполнения -

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]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...