8

次の問題があります: 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)))))

最後に計算された値を取得できないため (少なくとも方法がわからない!)、機能しません。それから私は考えました: OK、Loop-Recur を使用しましょう。これにより、時系列エントリに対応する値が得られますが、次のエントリでは、すべての計算を再度行う必要があります。反復は正しいことですが、関数には副作用があるため機能しませんでした。

だから私はこれにここで立ち往生しています。誰かが私にヒントを与えることができれば素晴らしいことです。

4

2 に答える 2

7

最終結果のみを気にする場合は、reduce;を使用します。各値を順番に変換した結果のシーケンスを取得する必要がある場合(各変換は前の値に依存します)、を使用しますreductionsclojure.contrib.seq-utils1.1およびclojure.core1.2にあります)。

以下でtransform-first-entryは、最初のエントリに対して実行したいことをすべて実行します(変換する必要がない場合は、reduce/の最初の引数を省略して、最後の引数としてではなくreductions使用できます)。は、前のエントリと現在のエントリを(この順序で)変換した結果を取得し、現在のエントリの変換結果を生成する関数です。entries(rest entriestransform-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...)

reductionsそれは怠惰であることに注意してください。

最初のエントリを変更せずに、質問テキストから後続のエントリに変換例を適用したい場合は、次を使用できます。

(defn transform-entry [prev-transformed current]
  (+ prev-transformed
     (/ current 2)))

の削減関数として

(reduce transform-entry series) ; ...or reductions
于 2010-07-13T14:49:29.867 に答える
3

ヒントが欲しいだけなら; の使用を検討してpartitionください。

ヒントよりも少し…</p>

(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)))))

これはテストされていませんが、動作するか、ほぼ動作するはずです:)

説明

(partition n i seq)seq長さn(この場合は 2) とオーバーラップ(この場合は 1) のリストをパーツに分割しi、次にそれらを で反復しfor、パーツで必要なことを行います。

于 2010-07-13T14:22:31.177 に答える