У меня есть следующая проблема: у Меня есть временной ряд больше чем с 10 000 записей, и я хочу выполнить некоторые вычисления с каждым из них. Это одно не было бы проблемой, но я должен привести последнее расчетное значение в порядок для получения следующего. Очень простая форма того, в чем я нуждаюсь, была бы похожа на это:
Val(n) = Val(n-1) + (time-series-entry / 2)
(или что-то как он!)
У меня нет идеи, как управлять этим. Просто выполнение чего-то вроде этого:
(defn calc-val
[time-series element]
(seq (cons (generate-val-element time-series element)
(calc-val time-series (inc element)))))
не работал бы, потому что не может (по крайней мере, я не знаю как!) получают последнее вычисленное значение. Затем я думал: хорошо, давайте использовать Цикл - Повторяются. Это дало бы мне значение, соответствующее записи временного ряда, НО для следующего я должен буду сделать все вычисления снова. Выполните итерации была бы правильная вещь, но она не работала, потому что функция имеет побочные эффекты.
Таким образом, я застреваю здесь на этом. Было бы замечательно, если кто-то мог бы дать мне подсказку.
Если вам просто нужна подсказка; изучите использование раздела
.
Немного больше, чем подсказка …
(defn calc-val
[time-series element]
(let [p (partition 2 1 time-series)]
(for [t p]
(let [first-value (first t)
second-value (second t)]
(do whatever you need to here)))))
Хотя это не было проверено, оно должно работать или быть близким к работе :)
Пояснение
(раздел ni seq)
разделяет seq
на части, в которых перечислены длины n
(в данном случае 2) с перекрытием i
(в данном случае 1), а затем мы перебираем те, которые имеют для
и делаем с деталями все, что захотим.
Если вас интересует только конечный результат, используйте reduce
; если вам нужно получить последовательность результатов преобразования каждого значения по очереди (где каждое преобразование зависит от предыдущих), используйте редукции
(можно найти в clojure.contrib.seq-utils
в 1.1 и в clojure.ядро
в 1.2).
Ниже transform-first-entry
делает все, что вы хотите сделать с первой записью (если вам не нужно каким-либо образом преобразовывать ее, вы можете просто опустить первый аргумент для уменьшить
/ сокращений
и использовать записи
, а не (остальные записи
в качестве последнего аргумента); transform-entry
функция, которая принимает результат преобразования предыдущей записи и текущей записи (в этом порядке) и выдает результат преобразования для текущей записи.
;;; only care about the final result
(reduce transform-entry
(transform-first-entry (first series))
(rest entries))
;;; need to get a seq of intermediate results
(reductions ...arguments as above...)
Обратите внимание, что редукции
является ленивым.
Предполагая, что вы хотите оставить первую запись без изменений и применить преобразование вашего примера из текста вопроса к последующим записям, вы можете использовать
(defn transform-entry [prev-transformed current]
(+ prev-transformed
(/ current 2)))
в качестве функции сокращения в
(reduce transform-entry series) ; ...or reductions