0

I have a Numpy array of shape N, 3, 2. I will call a combination each element of shape 3, 2 (So there are N combinations). I want to apply "tests" on values inside each combination. If a condition is not satisfied, I would like to delete the combination where the condition is not satisfied.

Let's say I have this array:

array[[[1, 1],
       [2, 2],
       [3, 3]],

      [[2, 1],
       [2, 2],
       [2, 3]],

      [[3, 1],
       [3, 2],
       [3, 3]]]

I want to check that all values on the left are > 1. Currently I do: myArr = myArr[myArr[:, :, 0] > 1]

Running this, it only delete the [1, 1] element, not the whole combination (i.e. [[1, 1], [2, 2], [3, 3]]).

How can I achieve this? Without for loops if possible ? (I have a high number of combinations)

Currently, my code is like:

#X is the left value and Y the right value, each combination having 3 elements like [X, Y] I used Xt or Yt with t=1 to 3 in my comments later.

Limit = 2
b = np.array([[[1, 1], [2, 2], [3, 3]],
              [[2, 1], [2, 2], [2, 3]],
              [[3, 1], [3, 2], [3, 3]],
              [[4, 3], [4, 2], [3, 1]]])
#All X > 0
b = b[b[:, :, 0] > 0].reshape(-1, 3, 2)

#X1 + Y1 <= X2
b = b[b[:, 0, 0] + b[:, 0, 1] <= b[:, 1, 0]].reshape(-1, 3, 2)

#X2 + Y2 <= X3
b = b[b[:, 1, 0] + b[:, 1, 1] <= b[:, 2, 0]].reshape(-1, 3, 2)

#X2 / X1
b = b[b[:, 1, 0] / b[:, 0, 0] <= Limit].reshape(-1, 3, 2)

#Y2 / Y1
b = b[b[:, 1, 1] / b[:, 0, 1] <= Limit].reshape(-1, 3, 2)

#X3 / X2
b = b[b[:, 2, 0] / b[:, 1, 0] <= Limit].reshape(-1, 3, 2)

#Y3 / Y2
b = b[b[:, 2, 1] / b[:, 1, 1] <= Limit].reshape(-1, 3, 2)

#X1 / X2
b = b[b[:, 0, 0] / b[:, 1, 0] <= Limit].reshape(-1, 3, 2)

#Y1 / Y2
b = b[b[:, 0, 1] / b[:, 1, 1] <= Limit].reshape(-1, 3, 2)

#X2 / X3
b = b[b[:, 1, 0] / b[:, 2, 0] <= Limit].reshape(-1, 3, 2)

#Y2 / Y3
b = b[b[:, 1, 1] / b[:, 2, 1] <= Limit].reshape(-1, 3, 2)

#Comb 1 != Comb 2
b = b[(b[:, 0, 0] != b[:, 1, 0]) & (b[:, 0, 1] != b[:, 1, 1])].reshape(-1, 3, 2)

#Comb 2 != Comb 3
b = b[(b[:, 1, 0] != b[:, 2, 0]) & (b[:, 1, 1] != b[:, 2, 1])].reshape(-1, 3, 2)
ZottoZ
  • 43
  • 1
  • 6
  • Check for ALL matches along the appropriate axis, hence : `myArr[(myArr[:, :, 0] > 1).all(axis=1)]`. – Divakar Aug 22 '19 at 06:53
  • Well, this test if, jointly, X are > 0. 1) I do a OR test not an AND, 2) my issue is how to delete a whole "combination" if a condition applied in one of the element inside the combination is not satisfied. Thanks – ZottoZ Aug 22 '19 at 07:41
  • That essentially doing ANY not-greater. Just break down into individual steps and study the outputs. – Divakar Aug 22 '19 at 07:57

1 Answers1

0

Try this:

import numpy as np
from numpy import array

arr = array([[[1, 1],
              [2, 2],
              [3, 3]],
             [[2, 1],
              [2, 2],
              [2, 3]],
             [[3, 1],
              [3, 2],
              [3, 3]]])


bool_array = arr > 1

indices = np.all(bool_array[:,:,0],axis = 1)

new_arr = arr[indices]
new_arr
>>> array([[[2, 1],
            [2, 2],
            [2, 3]],
           [[3, 1],
            [3, 2],
            [3, 3]]])
some_name.py
  • 777
  • 5
  • 16
  • Works for the first test, but how do adapt this for that test ? : #X1 + Y1 <= X2 b = b[b[:, 0, 0] + b[:, 0, 1] <= b[:, 1, 0]].reshape(-1, 3, 2) – ZottoZ Aug 22 '19 at 09:17
  • First of all I don´t understand `#X1 + Y1 <= X2 b = b[b[:, 0, 0] + b[:, 0, 1] <= b[:, 1, 0]].reshape(-1, 3, 2)`. The second point I just saw that I answered your question yesterday where I exactly showed you how to to that. So just read my answer from one day ago please: https://stackoverflow.com/questions/57570317/how-to-replace-for-loops-and-if-statements-with-numpy-arrays/57572047#57572047 – some_name.py Aug 22 '19 at 10:58