繁体   English   中英

懒散地合并(分组)巨大序列

[英]Merge (group-by) huge sequences lazily in clojure

例:

我们有两个通过读取csv创建的map的时间序列惰性序列。 这两个惰性序列在不同的日期开始:


INPUT
 lazy-seq1
  ({:date "20110515" :val1 123}
   {:date "20110516" :val1 143}
   {:date "20110517" :val1 1153} ...)
 lazy-seq2
  ({:date "20110517" :val2 151}
   {:date "20110518" :val2 1330} ...)
EXPECTED OUTPUT
 lazy-seq3 
  ({:date "20110515" :vals {:val1 123}}
   {:date "20110516" :vals {:val1 143}}
   {:date "20110517" :vals {:val1 1153 :val2 151}}
   {:date "20110518" :vals {:val1 ... :val2 1330}}
  ...))

确切地说,:date的类型不是字符串,而是按clj-time和:date强制对每个序列排序的Jodatime。

首选将是使用group-by函数,但是我想这不能创建lazy-seq。 我认为,分组依据需要急切的评估。

第二种选择是使用分区功能,但是由于缺乏封闭技巧,我无法将其应用于输入。

输入序列相当大(每个序列约1GB),我想一次计算很多(约100个)序列。 因此,我希望进行惰性评估以避免Outofmemory错误。

如果您的项目按日期排序,则可以轻松地对它们进行惰性合并(例如在合并排序算法中):

(defn merge-lazy [seq1 seq2]
  (cond (empty? seq1) seq2
        (empty? seq2) seq1
        (< (Integer/parseInt (:date (first seq1)))
           (Integer/parseInt (:date (first seq2)))) (cons (first seq1)
                                                      (lazy-seq (merge-lazy (rest seq1) seq2)))
        :else (cons (first seq2) (lazy-seq (merge-lazy seq1 (rest seq2))))))

它将按日期产生一个排序的惰性序列:

user> (def seq1
        '({:date "20110515" :val1 123}
          {:date "20110516" :val1 143}
          {:date "20110517" :val1 1153}))
#'user/seq1
user> (def seq2 '({:date "20110517" :val2 151}
                  {:date "20110518" :val2 1330}))

user> (merge-lazy seq1 seq2)
({:date "20110515", :val1 123} {:date "20110516", :val1 143} 
 {:date "20110517", :val2 151} {:date "20110517", :val1 1153} 
 {:date "20110518", :val2 1330})

然后您就可以按日期对生成的惰性序列进行分区(这也会产生惰性序列):

user> (partition-by :date (merge-lazy seq1 seq2))
(({:date "20110515", :val1 123}) 
 ({:date "20110516", :val1 143}) 
 ({:date "20110517", :val2 151} {:date "20110517", :val1 1153})
 ({:date "20110518", :val2 1330}))

所以接下来要做的就是使用map处理每个组

如果你有更多的输入序列,您可以使用同样的策略,只是重写merge-lazy可变ARGS(或只是reducemerge-lazy(reduce merge-lazy sequences) ,这也将产生序列合并的懒惰SEQ)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM