Выбор строк массива numpy, который содержит все заданные значения - PullRequest
0 голосов
/ 03 июня 2019

У меня есть np.array:

matrix = np.array([['A', 'B', 'C'], ['A', 'B', np.nan], ['C', np.nan, np.nan] ])

, и я хочу эффективно выбрать все строки, содержащие данные значения

samples = ['C', 'A']

, но когда я делаю:

mask = np.isin(matrix, samples)

Я получаю

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

Как эффективно получить маску, если значение True только в тех строках, которые содержат оба значения?

Я фокусируюсь на эффективности, потому что она редкаяи большая матрица.

Спасибо, предварительные оценки.

Ответы [ 4 ]

0 голосов
/ 07 июня 2019

Я наконец использую:

#Filter
test_elements = ['A', 'B']
mask = np.isin(matrix, test_elements)
vec_mask = np.isin(mask.sum(axis=1), [len(test_elements)])
ids = np.where(vec_mask)
existence = matrix[ids]

Спасибо за помощь, ребята.

0 голосов
/ 03 июня 2019

Если вы хотите что-то векторизовать, я бы предложил сделать это сравнение, трансформировав его в 3D и передав в третьем измерении.Затем для каждого среза проверьте каждую строку, чтобы увидеть, есть ли что-либо, что True.Наконец, если мы видим, что для каждой строки каждый элемент равен True, то это результат, который мы должны вернуть.

In [40]: matrix = np.array([['A', 'B', 'C'], ['A', 'B', np.nan], ['C', np.nan, np.nan] ])

In [41]: samples = ['C', 'A']

In [42]: samples = np.array(samples)

In [43]: mask = matrix[...,None] == samples[None,None]

In [44]: mask
Out[44]:
array([[[False,  True],
        [False, False],
        [ True, False]],

       [[False,  True],
        [False, False],
        [False, False]],

       [[ True, False],
        [False, False],
        [False, False]]])

In [45]: mask = np.any(mask, axis=1)

In [46]: mask
Out[46]:
array([[ True,  True],
       [False,  True],
       [ True, False]])

In [47]: mask = np.all(mask, axis=1)

In [48]: mask
Out[48]: array([ True, False, False])

Чтобы сделать это более коротко:

# Define data
matrix = np.array([['A', 'B', 'C'], ['A', 'B', np.nan], ['C', np.nan, np.nan] ])
samples = ['C', 'A']

# Solution
mask = np.all(np.any(matrix[...,None] == np.array(samples)[None,None], axis=1), axis=1)

Обратите внимание, что это, вероятно, не очень хорошо с большими разреженными матрицами ....

0 голосов
/ 03 июня 2019

Вот псевдокод, который может вам помочь:

idxRows = []
for idx, i in enumerate(mask):
    if True in i:
        idxRows.append(idx)

Это даст вам индексы всех строк, которые содержат указанные образцы.

0 голосов
/ 03 июня 2019

Мой первый подход будет

[np.isin(samples, row).all() for row in matrix]
# [True, False, False]

(но, если честно, ничего не могу сказать об эффективности или производительности ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...