Я пишу программу на Python, которая обрабатывает некоторые данные, созданные во время экспериментов, и ей необходимо оценить наклон данных. Я написал код, который делает это довольно хорошо, но это ужасно медленно (и я не очень терпелив). Позвольте мне объяснить, как этот код работает:Python: скользящее окно переменной ширины
1) Она захватывает небольшой кусочек данных размером йх (начиная с 3-х точек данных)
2) Он оценивает ли разница (т.е. | у (х +) -y (x-dx) |) больше некоторого минимального значения (40x std. шума)
3) Если разница достаточно велика, она рассчитает наклон с использованием регрессии OLS. Если разница слишком мала, это увеличит йх и повторить цикл с новым йхом
4) Это продолжается для всех точек данных
[См обновленного кода далее вниз]
Для DataSize из около 100 тыс. измерений, это занимает около 40 минут, тогда как остальная часть программы (она обрабатывает больше, чем только этот бит) занимает около 10 секунд. Я уверен, что есть гораздо более эффективный способ выполнения этих операций, не могли бы вы, ребята, помочь мне?
Благодаря
EDIT:
Итак, у меня есть проблема решена с помощью только двоичного поиска, ограничивая число допустимых шагов на 200. Я благодарю всех за вход и я выбран ответ, который помог мне больше всего.
FINAL ОБНОВЛЕНО КОД:
def slope(self, data, time):
(wave1, wave2) = wt.dwt(data, "db3")
std = 2*np.std(wave2)
e = std/0.05
de = 5*std
N = len(data)
slopes = np.ones(shape=(N,))
data2 = np.concatenate((-data[::-1]+2*data[0], data, -data[::-1]+2*data[N-1]))
time2 = np.concatenate((-time[::-1]+2*time[0], time, -time[::-1]+2*time[N-1]))
for n in xrange(N+1, 2*N):
left = N+1
right = 2*N
for i in xrange(200):
mid = int(0.5*(left+right))
diff = np.abs(data2[n-mid+N]-data2[n+mid-N])
if diff >= e:
if diff < e + de:
break
right = mid - 1
continue
left = mid + 1
leftlim = n - mid + N
rightlim = n + mid - N
y = data2[leftlim:rightlim:int(0.05*(rightlim-leftlim)+1)]
x = time2[leftlim:rightlim:int(0.05*(rightlim-leftlim)+1)]
xavg = np.average(x)
yavg = np.average(y)
xlen = len(x)
slopes[n-N] = (np.dot(x,y)-xavg*yavg*xlen)/(np.dot(x,x)-xavg*xavg*xlen)
return np.array(slopes)
Не застревает ли он в конце, где вы больше не можете увеличить 'i' (если абсолютное значение меньше' e')? – vhallac
Что касается исходного вопроса, я бы посмотрел, можно ли немного уменьшить i, вместо того, чтобы сбрасывать каждый цикл в 0. Я сначала думал, что уменьшение на один будет достаточно, но это не работает во всех случаях. – vhallac
Могу ли я спросить, какие окна? Из того, что я вижу, с этим ничего не делается. – arynaq