假设我有一组元组要由Cascalog处理,格式类似于[Date, Name, Value]。
2014-01-01 Pizza 3
2014-01-01 Hamburger 4
2014-01-01 Cheeseburger 2
2014-01-02 Pizza 1
2014-01-02 Hamburger 2考虑到我有一个像[Pizza, Hamburger, Cheeseburger]这样的列的列表,我想转换/枢轴数据,如下所示:
Date Pizza Hamburger Cheeseburger
2014-01-01 3 4 2
2014-01-02 1 2 0在卡斯卡洛格做这件事最好的方法是什么?
发布于 2014-04-29 08:03:04
有一种方法可以做到:
(:use cascalog.api)
(def input
[["2014-01-01" "Pizza" 3]
["2014-01-01" "Hamburger" 4]
["2014-01-01" "Cheeseburger" 2]
["2014-01-02" "Pizza" 1]
["2014-01-02" "Hamburger" 2]])
(defn init-aggregate [k v]
{k v})
(def combine-aggregate
(partial merge-with +))
(defparallelagg aggregate
:init-var #'init-aggregate
:combine-var #'combine-aggregate)
(defn select-values [hashmap keyseq]
(map #(get hashmap %) keyseq))
(def columns
["Pizza" "Hamburger" "Cheeseburger"])
(defn transpose [data]
(<- [?date !pizza !hamburger !cheeseburger]
((<- [?date ?sum]
(data ?date ?name ?value)
(aggregate ?name ?value :> ?sum))
?date ?sum)
(select-values ?sum columns :> !pizza !hamburger !cheeseburger)))
(?- (stdout) (transpose input))让我们快速浏览一下代码:
大多数操作发生在transpose函数中,它包含两个查询:
?name ?value对聚合到?sum映射中。select-values从?sum映射中获取列的值,并进入最终的结果行。因为我们知道列是Pizza, Hamburger, Cheeseburger,所以我们可以简单地将它们硬编码到查询中。如果您想知道如何使列动态,请阅读Nathan在在Cascalog创建一个新闻提要上的博客文章。
注意,我们必须将列表示为可空变量(使用!),因为不是每个列都有给定行的值。如果要避免null结果,可以将select-values更改为使用0作为默认值。
(一个警告是,这不会在最后的输出中产生任何头,因此必须作为后处理步骤来完成。)
https://stackoverflow.com/questions/23342939
复制相似问题