0
votes

I have a list of boolean arrays constructed using the numpy where function, e.g.:

A[0] = [False, False, True, True, True, False, False,False,False,False]
A[1] = [False, False, False, False,False,False, True, True, True,False]
A[2] = [False,True, True, True, False, False, False, False,False,False]
...

A few notes:

  • the real arrays have something like 10 000 elements
  • there are several "true" windows on each array
  • the "true" windows might overlap from array to array
  • all arrays have the same length L

I need to:

1) combine all arrays into one single array with length L that will contain all "True" values

2) recover for each "True" window the inicial and final index

any ideas?

Thanks!

EDIT

The expected result is: R = [False,True, True, True, True, False, True, True, True, False]

In terms of code:

import numpy as np

data = np.arange(1,100)

list_of_lists = [[5,10], [15,25], [45,85]]

A = [np.where((data < list[1]) & (data > list[0]))[0] for list in list_of_lists]

Output:

 >>> print A
 [array([5, 6, 7, 8]), array([15, 16, 17, 18, 19, 20, 21, 22, 23]), array([45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
   62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
   79, 80, 81, 82, 83])]

the desired result:

 R = [[5,8],[15,23],[45,83]]
2
Do you have any ideas about how to do this? Have you written any code for this? We don't write code for people from scratch, no.ForceBru
It is hard to understand what's the desired outputMaor Veitsman
Let us know the required outputSandeep Lade
Welcome to SO. Unfortunately this isn't a discussion forum, tutorial, or a code writing service. Please take the time to read How to Ask and the links it contains. You should spend some time working your way through the Tutorial, practicing the examples. It will give you an introduction to the tools Python has to offer and you may even start to get ideas for solving your problem. The Numpy docs should help too.wwii
True or False --> True.wwii

2 Answers

0
votes

I am not sure what you mean when you say "Combine all arrays into one single array with length L that will contain all "True" values". However, the the second item, recovering the initial and final indices for all true windows was kinda fun:

A = []
A.append([False,False,True, True, True, False,False,False,False,False])
A.append([False,False,False,False,True, True, True, False,False,False])
A.append([False,True, True, True, False,False,False,False,False,False])

r =      [False,True, True, True, True, True, True, False,False,False]
# r is the desired result, with start index of 1 and end index of 6

L = len(A[0])
W = []

start = True
w = set()
for i in range(L):
    if start: # beginning of window
        for a in A:  
            if a[i] is True:  # found the start of the window
                w.add(i)      # mark it
                start = False # start looking for the end of the window
                break
    else:
        end = True # until proven otherwise
        for a in A:
            if a[i] is True:  # nope, not the end, keep looking
                end = False   # proof
                break
        if end is True:  # all false, this is the end
            w.add(i-1)   # mark it
            W.append(w)  # save it
            w = set()    # start over
            start = True

print (W) 
0
votes

Let us first simplify your example to a case where there is an overlap between two sub-arrays.

a = np.array([[False, False, True, True], [True, False, False, False]])

so from what I gathered from the question, the expected output would be:

[array([1, 4])]

as that is where the "True" window's start and finish is (indexes 1 and 4).

To achieve this result, we need to first flatten a in order to gt a 1-dimensional array of the concatenated sub-arrays. This is done with a.flatten(). Which gives:

array([False, False,  True,  True,  True, False, False, False], dtype=bool)

Now, we need to find the indexes where the value flips state (i.e. True --> False or False --> True). To do this with, we can compare the array of a.flatten() without the first element to the array of a.flatten() without the last element. Then use np.where on this boolean array to get the indexes of state change.

N.B. the above technique was originally from this answer` by @Kith.

So to implement that, we can do the following:

np.where(a.flatten()[:-1] != a.flatten()[1:])[0]

which gives us the indexes of state change:

(array([1, 4], dtype=int32),)

which is actually one off as it is where the state changes, so before the start of the first window.

We then need to chunk this array into 2s. This is done with np.split():

indexes = np.where(a.flatten()[:-1] != a.flatten()[1:])[0] 
windows = np.split(indexes, len(indexes) / 2)

which gives us a list of arrays of length 2 indicating the start and finish of a window:

[array([1, 4], dtype=int32)]