在 Clojure 中迭代时间序列时出现问题
我有以下问题: 我有一个包含超过 10000 个条目的时间序列,我想对每个条目执行一些计算。仅此一点不会成为问题,但我需要获取最后一个计算值才能获得下一个值。我需要的一个非常简单的形式如下所示:
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)))))
不会工作,因为不能(至少我不知道如何!)获得最后的计算值。 然后我想:好吧,我们使用 Loop-Recur 吧。这将为我提供与时间序列条目相对应的值,但对于下一个时间序列条目,我将不得不再次进行所有计算。 迭代是正确的事情,但它不起作用,因为该函数有副作用。
所以我就被困在这里了。如果有人能给我提示,那就太好了。
I have the following problem:
I have a time-series with more than 10000 entries and I want to perform some calculations with each of them. This alone wouldn't be a problem, but I need to get the last calculated value in order to get the next one. A very simple form of what I need would look like this:
Val(n) = Val(n-1) + (time-series-entry / 2)
(or something like it!)
I don't have any idea how to manage this. Simply doing something like this:
(defn calc-val
[time-series element]
(seq (cons (generate-val-element time-series element)
(calc-val time-series (inc element)))))
wouldn't work because can't (at least I don't know how!) get the last computed value.
Then I thought: OK, let's use Loop-Recur. This would give me the value corresponding to the time-series entry BUT for the next one I would have to do all the computations again.
Iterate would be the right thing, but it didn't work because the function has side effects.
So I'm stuck here on this one. It would be great if someone could give me a hint.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果你只关心最终结果,请使用
reduce
;如果您需要获取依次转换每个值的结果序列(其中每个转换取决于之前的转换),请使用reductions
(可在clojure.contrib.seq-utils
中找到) 1.1 中的 code> 和 1.2 中的 clojure.core 中)。下面,
transform-first-entry
对第一个条目执行您想要执行的任何操作(如果您不需要以任何方式转换它,您可以省略的第一个参数减少
/减少
并使用entries
而不是(剩余条目
作为最后一个参数); code> 是一个函数,它获取前一个条目和当前条目(按此顺序)的转换结果,并为当前条目生成转换结果。请注意
,假设您想要这样做。保留第一个条目不变,并将示例转换从问题文本应用到后续条目,您可以
在
If you only care about the final result, use
reduce
; if you need to get a seq of results of transforming each value in turn (where each transformation depends on the previous ones), usereductions
(found inclojure.contrib.seq-utils
in 1.1 and inclojure.core
in 1.2).Below,
transform-first-entry
does whatever you want to do to the first entry (if you don't need to transform it in any way, you can just leave out the first argument toreduce
/reductions
and useentries
rather than(rest entries
as the final argument);transform-entry
is the function which takes the result of transforming the previous entry and the current entry (in this order) and produces the transformation result for the current entry.Note that
reductions
is lazy.Assuming you wanted to leave the first entry unchanged and apply your example transformation from the question text to the subsequent entries, you could use
as the reduction function in
如果你只是想要一个提示;考虑使用
分区
< /a>.不仅仅是一个提示......
虽然这还没有经过测试,但它应该可以工作或接近工作:)
解释
(partition ni seq)< /code> 将
seq
分成长度为n
(本例中为 2)且重叠i
(本例中为 1)的列表部分,并且然后我们用for
迭代这些部分,并对这些部分执行我们想要的操作。If you just want a hint; look into using
partition
.For a little more than a hint…
Though this hasn't been tested, it should work or be close to working :)
Explanation
(partition n i seq)
separatesseq
into parts that lists of lengthn
(2 in this case) with overlapi
(1 in this case), and then we iterate over those withfor
, and do what we want with the parts.