n_level = range(1, steps + 2)
steps
is user input, using multi-index dataframe
df = {'crest': [754, 755, 762, 785], 'trough': [752, 725, 759, 765], 'L1T': [761, 761, 761, 761], 'L2T': [772, 772, 772, 772], 'L3T': [783, 783, 783, 783], 'L4T': [794, 794, 794, 794], 'L1M': [740, 740, 740, 740], 'L2M': [729, 729, 729, 729], 'L3M': [718, 718, 718, 718], 'L4T': [707, 707, 707, 707]}
for i in n_level:
if df['Crest'] >= df[f'L{i}T']:
df['Marker'] = i
elif df['Trough'] <= df[f'L{i}M']:
df['Marker'] = -i
else:
df['Marker'] = 0
I am expecting below df with the col marker
df = {'crest': [754, 755, 762, 785], 'trough': [752, 725, 759, 765], 'L1T': [761, 761, 761, 761], 'L2T': [772, 772, 772, 772], 'L3T': [783, 783, 783, 783], 'L4T': [794, 794, 794, 794], 'L1M': [740, 740, 740, 740], 'L2M': [729, 729, 729, 729], 'L3M': [718, 718, 718, 718], 'L4T': [707, 707, 707, 707], 'Marker': [0, -2, 1, 3]},
The if statement is returning True or False, using that can we convert it to the ith Value (+/-)
what I need is another col df['Marker'], which will measure if the crest or trough crossed L{i}T or L{i}M, any breach on the upside in case of the crest and breach on the downside in case of the trough
this can be achieved easily using binary search, there are many ways to apply that(NumPy, bisect). I would recommend the library bisect.
Added Buu for the Crest and See for the Trough, so that code and differentiate the segments. You can choose anything
def marker_up(row):
n_row = [row[col] for col in columns if "Buu" in col]
n_high = row['Crest']
if n_high in n_row:
q = bs.bisect_left(n_row, n_high)
q = max(0, q)
return q
else:
q_mod = bs.bisect_left(n_row, n_high)
q_mod -= 1
q_mod = max(0, q_mod)
return q_mod
Marker_up = df.apply(marker_up, axis=1)
def marker_down(row):
n_row = [row[col] for col in columns if "See" in col]
n_low = row['Trough']
if n_low in n_row:
q = bs.bisect_left(n_row, n_low)
q = q - len(n_row)
return q
else:
q_mod = bs.bisect_left(n_row, n_low)
q_mod = q_mod - len(n_row)
return q_mod
Marker_down = df.apply(marker_down, axis=1)
df['Marker'] = Marker_up + Marker_down
return df
Don't use iloc, dict or iterrrows if you have large df. A vectorized form will help to run code faster.