3

I am a python new bie.
I have two list of lists like this:

A = List[List[float,float]]   
B = List[List[float,float]]  

both different sizes Ex :

A has [time, value]  
B has [start_time, end_time]  


A = [[0.0,10.0] , [1.0,10.0], [2.0,10.0], [3.0,10.0], [4.0,10.0],  [5.0,10.0],  [6.0,10.0]]
B = [[0.0,2.0], [5.0,6.0]]     

What I am trying to do is :
if A has a time which is not in B, I should make the corresponding 'value' in A to zero.

So output would be :

[[0.0,10.0] , [1.0,10.0], [2.0,10.0], [3.0,0.0], [4.0,0.0],  [5.0,10.0],  [6.0,10.0]]

i.e if a time segment in B has no corresponding time value present in A, the value corresponding to that time should be made zero. In this case, the values between 2 and 5 are there in B , so partner values of'3' and '4' in A are made to zeroes.

Please tell me how to do it. I have referred here: Python - How to change values in a list of lists? and List of lists into numpy array

So One idea i got was to convert B into single list and then compare values from AA and A. However I haven't made much progress.

AA = numpy.hstack(B) # for getting array of times
for i in 1: len(AA):
     if (AA[i]==A[
DJ_Stuffy_K
  • 615
  • 2
  • 11
  • 29

4 Answers4

3

For simple problems, a nested loop design can often get you to a quick solution without needing to worry about the specifics of list-flattening functions.

for i in range(len(A)):
    time = A[i][0]
    isValidTime = False
    for time_segment in B:
        if time_segment[0] <= time <= time_segment[1]:
            isValidTime = True
            break
    if not isValidTime:
        A[i][1] = 0.0

Edit: Just to be clear, including the 'break' statement isn't necessary to get to the solution, but it helps avoid unnecessary computation. If we've determined that an item in A does have a valid time, we can safely stop searching through the time segments in B and move on to the next item of A.

ehusby
  • 96
  • 5
2

If you flatten B, then you can compare it:

A = [[0.0, 10.0], [1.0, 10.0], [2.0, 10.0], [3.0, 10.0], [4.0, 10.0], [5.0, 10.0], [6.0, 10.0]]
B = [[0.0, 2.0], [5.0, 6.0]]

Bvals = [item for sublist in B for item in sublist]
print(Bvals)
newA = [x if x[0] in Bvals else [x[0], 0.0] for x in A]
print(newA)

Outputs:
[0.0, 2.0, 5.0, 6.0]
[[0.0, 10.0], [1.0, 0.0], [2.0, 10.0], [3.0, 0.0], [4.0, 0.0], [5.0, 10.0], [6.0, 10.0]]
Jose A. García
  • 888
  • 5
  • 13
2

I suppose the B list contains time intervals, right? In that case, you can do something like the following:

updated = [x if any([start <= x[0] end <= for start, end in B]) else [x[0], 0] for x in A]

That may be a bit too compact for some people, but it essentially does the same as the following:

updated = []
for time, value in A:
    for start, end in B:
        if start <= time and time <= end:
            updated.append([time, value])
            break
    updated.append([time, 0])

On a side note, if you are doing interval checking, this is probably not the most efficient way to do it. Take a look at interval trees, which is a data structure for performing various interval-related queries (yours included).

bow
  • 2,503
  • 4
  • 22
  • 26
2

A Pythonic one-liner:

[[t,v if any(s <= t and t <= e for s,e in B) else 0.0] for t,v in A]  

which gives:

[[0.0, 10.0], [1.0, 10.0], [2.0, 10.0], [3.0, 0.0], [4.0, 0.0], [5.0, 10.0], [6.0, 10.0]]
Community
  • 1
  • 1
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54