Проблема с итерацией по временному ряду в clojure

У меня есть следующая проблема: у Меня есть временной ряд больше чем с 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)))))

не работал бы, потому что не может (по крайней мере, я не знаю как!) получают последнее вычисленное значение. Затем я думал: хорошо, давайте использовать Цикл - Повторяются. Это дало бы мне значение, соответствующее записи временного ряда, НО для следующего я должен буду сделать все вычисления снова. Выполните итерации была бы правильная вещь, но она не работала, потому что функция имеет побочные эффекты.

Таким образом, я застреваю здесь на этом. Было бы замечательно, если кто-то мог бы дать мне подсказку.

8
задан Tiasmadu 13 July 2010 в 14:05
поделиться

2 ответа

Если вам просто нужна подсказка; изучите использование раздела .

Немного больше, чем подсказка

(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), а затем мы перебираем те, которые имеют для и делаем с деталями все, что захотим.

3
ответ дан 5 December 2019 в 17:33
поделиться

Если вас интересует только конечный результат, используйте 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
7
ответ дан 5 December 2019 в 17:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: