Короткий ответ (более быстрая реализация)
следующий код в 6 раз быстрее:
import numpy as np
def my_shift(x, i):
first = np.array([np.nan]*i)
return np.append(first, x[:-i])
result = ((df2['BidClose'].values - df2['BidLow'].values)/(df2['BidHigh'].values - df2['BidLow'].values))
for i in range(1, 49, 1):
df2.loc[:,'Close_T_period_'+str(i)] = my_shift(result, i)
Длинный ответ (объяснение)
Две основные проблемы узкого места в вашемкод:
- На каждой итерации вы пересчитываете одни и те же значения, единственное отличие состоит в том, что каждый раз они сдвигаются по-разному;
- Операция сдвига панд очень медленная для вашей цели.
, поэтому мой код просто решает две проблемы.По сути, я вычисляю результат только один раз и использую цикл только для сдвига (проблемы №1 улучшены), и я реализовал свою собственную функцию сдвига, которая добавляется перед исходным массивом i
значения NaN и обрезает последние i
.
Время выполнения
С кадром данных с 5000 строками эталон времени дает:
42 ms ± 1.79 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
, с моим решением я получил:
7.62 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
ОБНОВЛЕНИЕ
Я пытался реализовать решение с применением:
result = ((df2['BidClose'].values - df2['BidLow'].values)/(df2['BidHigh'].values - df2['BidLow'].values))
df3 = df.reindex(df2.columns.tolist() +[f'Close_T_period_{i}' for i in range(1, 2000)], axis=1)
df3.iloc[:, 9:] = df3.iloc[:, 9:].apply(lambda row: my_shift(result, int(row.name.split('_')[-1])))
В моем тесте это решение выглядит немного медленнее, чем первое.