"previous_smaller_index" можно найти, используя векторизованное сравнение с широковещательной передачей с argmax
.
«предыдущий_1_индекс» можно решить с помощью groupby
и idxmax
на маске cumsum
med.
m = df.value.eq(1)
u = np.triu(df.value.values < df.value[:,None]).argmax(1)
v = m.cumsum()
df['previous_smaller_index'] = np.where(m, -1, len(df) - u - 1)
df['previous_1_index'] = v.groupby(v).transform('idxmax').mask(m, -1)
df
index value previous_smaller_index previous_1_index
0 0 1 -1 -1
1 1 1 -1 -1
2 2 2 1 1
3 3 3 2 1
4 4 2 1 1
5 5 1 -1 -1
6 6 1 -1 -1
Если вы хотите, чтобы эти строки были одним, вы можете объединить несколько строк в одну:
m = df.value.eq(1)
df['previous_smaller_index'] = np.where(
m, -1, len(df) - np.triu(df.value.values < df.value[:,None]).argmax(1) - 1
)[::-1]
# Optimizing @SpghttCd's `previous_1_index` calculation a bit
df['previous_1_index'] = (np.where(
m, -1, df.index.where(m).to_series(index=df.index).ffill(downcast='infer'))
)
df
index value previous_1_index previous_smaller_index
0 0 1 -1 -1
1 1 1 -1 -1
2 2 2 1 1
3 3 3 1 2
4 4 2 1 1
5 5 1 -1 -1
6 6 1 -1 -1
Общая производительность
Настройка и тест производительности были выполнены с использованием perfplot
. Код можно найти по этой сущности .

Время относительно (логарифмическая шкала y).
previous_1_index
Производительность
Суть с соответствующим кодом.
