I have a list of booleans
l = [False, False, False, True, False, False, False]
that I want to turn into
l_new = [False, False, False, True, True, True, False]
That means, whenever there is a True in my list I want to switch the two (for example) following values to true. My solution is
def lagged_effect(l, lag):
l_new = []
L_iter = iter(l)
for elem in L_iter:
if elem == True:
l_new.extend([True]*lag)
if lag == 1:
next(L_iter)
if lag == 2:
next(L_iter)
next(L_iter)
if lag == 3:
next(L_iter)
next(L_iter)
next(L_iter)
if lag == 4:
next(L_iter)
next(L_iter)
next(L_iter)
next(L_iter)
if lag > 4:
print("not defined")
if elem == False:
l_new.append(False)
return l_new
print(l_new)
lagged_effect(l, lag=2)
Since I want to implement this more often, I was wondering if there might be a more compact and efficient solution. Especially the next implementation annoys me.
CodePudding user response:
Using list shift and zip with boolean or
l = [False, False, False, True, False, False, False]
out = [x or y or z for x, y, z in zip(l, [False] l, [False]*2 l)]
print(out)
[False, False, False, True, True, True, False]
Option for any lag
lag = 4
l = [False, False, False, True, False, False, False, False, False, True, False, False, False, False, True]
out = [bool(sum(z)) for z in zip(*[[False] * n l for n in range(lag 1)])]
print(out)
[False, False, False, True, True, True, True, True, False, True, True, True, True, True, True]
CodePudding user response:
You can write a custom function:
l = [False, False, False, True, False, False, False]
def lag_true(l, lag=2):
out = []
last = 0
for v in l:
if v: # if True, set up last to lag value
last = lag
out.append(True)
elif last: # if last (>0, implicit)
out.append(True) # add True
last -= 1 # decrease last
else: # we have a False and are far from last True
out.append(False)
return out
lag_true(l)
# [False, False, False, True, True, True, False]
lag_true(l, lag=3)
# [False, False, False, True, True, True, True]
Vectorial alternative using pandas
import pandas as pd
LAG = 2
out = pd.Series(l).rolling(LAG 1, min_periods=1).max().astype(bool).to_list()
# [False, False, False, True, True, True, False]
CodePudding user response:
This is a possible solution:
l_new = l.copy()
for i in range(len(l) - 2):
if l[i]: l_new[i 1] = l_new[i 2] = True
l_new[-1] = True if len(l) > 1 and l[-2] else l_new[-1]