Объединить несколько масок разных размеров

#python #arrays #numpy #merge #mask

#python #массивы #numpy #объединить #маска

Вопрос:

Я хочу объединить несколько масок в большом массиве, который не имеет одинакового размера. Вторые маски создаются после применения первой маски и так далее к произвольному количеству масок. В качестве примера, допустим, у нас есть следующий массив и создаем из него маску:

 A = np.arange(10)
mask1 = (A <= 5)
  

Теперь мы хотим применить другую маску, но только к данным, проходящим через mask1, вот так:

 mask2 = (A[mask1] % 2 == 0)
  

Чтобы получить незамаскированные данные, вы могли бы сделать:

 D = A[mask1][mask2]
  

Однако, если у вас есть произвольное количество масок, каждая из которых была применена после последней маски, это стало бы довольно громоздким. Есть ли удобный способ объединить маски, даже если они разного размера, но построены из одного и того же массива?

Очевидно, я мог бы сделать,

 mask = (A <= 5 amp; A % 2 == 0)
  

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

Заранее спасибо.

Комментарии:

1. Если у вас есть список таких масок, вы можете выполнять цикл и на каждой итерации получать фрагменты. Итак, что-то вроде A = A[mask_each_iteration] или, чтобы не уничтожать входной массив, скопируйте A в выходной массив: out = A.copy() а затем выполните такую нарезку в цикле? Поскольку mask2 это будет зависеть от mask1 и так далее, вам потребуется некоторый итеративный процесс.

2.Я думаю, сработало бы следующее: total_mask = np.zeros(len(mask1)) q = 0 for i in range(len(mask1)): if mask1[i] == 1: total_mask[i] = (mask2[q] == 1) q = 1 Однако это не кажется очень красивым способом сделать это, но это может просто сработать.

Ответ №1:

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

Таким образом, мы могли бы сделать —

 idx1 = np.flatnonzero(mask1) # Store indices
idx2 = np.flatnonzero(mask2)
final_idx = idx1[idx2]
  

Мы бы использовали final_idx для индексации во входном массиве для окончательного выбора.

Чтобы распространить это на общее количество масок, итерационный процесс будет выглядеть примерно так —

 list_of_masks = [mask1,mask2,mask3]
idx = np.arange(A.shape[0])
for m in list_of_masks:
    idx = idx[np.flatnonzero(m)]
  

Пример запуска —

 In [104]: A = np.arange(20)

In [105]: # Let's create three iterative masks
     ...: mask1 = (A <= 5)
     ...: mask1[1] = 0
     ...: mask1[2] = 0
     ...: mask2 = (A[mask1] % 2 == 0)
     ...: mask3 = (A[mask1][mask2] % 3 == 0)
     ...: 

In [106]: A[mask1][mask2][mask3] # Original approach
Out[106]: array([0])

In [107]: list_of_masks = [mask1,mask2,mask3]
     ...: idx = np.arange(A.shape[0])
     ...: for m in list_of_masks:
     ...:     idx = idx[np.flatnonzero(m)]
     ...:     

In [108]: A[idx] # New approach to use final idx
Out[108]: array([0])