Эту операцию по своей природе сложно векторизовать, поскольку массив не отсортирован, а индексы, по-видимому, не представляют диапазоны одинакового размера.Я могу предложить превратить это в понимание списка, чтобы обойти накладные расходы с apply
, но после этого вы сами.
df['maxvalue'] = [
df['value'].values[int(s):int(e)].max() if pd.notna([s,e]).all()
else np.nan for s, e in zip(df['idxmin'], df['idxmax'])
]
df.head()
index value idxmin idxmax maxvalue
0 0 300 NaN NaN NaN
1 1 200 NaN NaN NaN
2 2 100 NaN NaN NaN
3 3 200 0.0 2.0 300.0
4 4 300 1.0 2.0 200.0
ВДля того, чтобы извлечь из этого максимум пользы, необходимо перенести как можно больше тяжелой работы с панд на болванку.Я вижу ускорение в 15 раз на моей машине только на небольшом DataFrame с 1000 строками.
df_ = df
df = pd.concat([df_] * 1000, ignore_index=True)
%timeit df.apply(
lambda x: df['value'].loc[x['idxmin']:x['idxmax']].max(), axis=1)
%%timeit
[
df['value'].values[int(s):int(e)].max() if pd.notna([s,e]).all()
else np.nan for s, e in zip(df['idxmin'], df['idxmax'])
]
4.79 s ± 68.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
268 ms ± 3.74 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)