В основном я пишу функцию поиска пиков, которая должна быть в состоянии превзойти scipy.argrelextrema
в бенчмаркинге.Вот ссылка на данные, которые я использую, и код:
https://drive.google.com/open?id=1U-_xQRWPoyUXhQUhFgnM3ByGw-1VImKB
Если срок действия этой ссылки истечет, данные можно найти в онлайн-загрузчике исторических данных банка dukascopy.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('EUR_USD.csv')
data.columns = ['Date', 'open', 'high', 'low', 'close','volume']
data.Date = pd.to_datetime(data.Date, format='%d.%m.%Y %H:%M:%S.%f')
data = data.set_index(data.Date)
data = data[['open', 'high', 'low', 'close']]
data = data.drop_duplicates(keep=False)
price = data.close.values
def fft_detect(price, p=0.4):
trans = np.fft.rfft(price)
trans[round(p*len(trans)):] = 0
inv = np.fft.irfft(trans)
dy = np.gradient(inv)
peaks_idx = np.where(np.diff(np.sign(dy)) == -2)[0] + 1
valleys_idx = np.where(np.diff(np.sign(dy)) == 2)[0] + 1
patt_idx = list(peaks_idx) + list(valleys_idx)
patt_idx.sort()
label = [x for x in np.diff(np.sign(dy)) if x != 0]
# Look for Better Peaks
l = 2
new_inds = []
for i in range(0,len(patt_idx[:-1])):
search = np.arange(patt_idx[i]-(l+1),patt_idx[i]+(l+1))
if label[i] == -2:
idx = price[search].argmax()
elif label[i] == 2:
idx = price[search].argmin()
new_max = search[idx]
new_inds.append(new_max)
plt.plot(price)
plt.plot(inv)
plt.scatter(patt_idx,price[patt_idx])
plt.scatter(new_inds,price[new_inds],c='g')
plt.show()
return peaks_idx, price[peaks_idx]
Он в основном сглаживает данные, используя быстрое преобразование Фурье (FFT), затем берет производную, чтобы найти минимальный и максимальный индексы сглаженных данных, а затем находит соответствующие пики для несглаженных данных.Иногда найденные пики не являются идеальными из-за некоторых эффектов сглаживания, поэтому я запускаю цикл for для поиска более высоких или более низких точек для каждого индекса между границами, указанными l
.Мне нужна помощь в векторизации этого цикла for
!Я понятия не имею, как это сделать.Без цикла for
мой код примерно на 50% быстрее, чем scipy.argrelextrema
, но цикл for замедляет его.Так что, если я найду способ векторизовать его, это будет очень быстрая и очень эффективная альтернатива scipy.argrelextrema
.Эти два изображения представляют данные без и с циклом for
соответственно.
![With the 'for' loop, peaks are much better](https://i.stack.imgur.com/nOMIE.png)