List Clojure:列出单个键的值
我来自Python世界,在那里很容易进行平均/分组。但我正在用clojure编程,我想从一个大的查询结果中计算每个文章ID的平均值 格式化查询结果后,我得到了类似的结果(这是一个示例,结果要大得多): 我想先有这样的想法: (“123”[233320]“234”[25]) 这就是想法,最终结果将是: ({:文章编号“123”:平均276.5}{:文章编号“234”:平均25}) 所以我需要两个步骤:列出值,然后应用均值函数。第二部分对我来说听起来不错,但我在第一步就被绊倒了:列出值 1) 方法1 我定义:List Clojure:列出单个键的值,list,join,clojure,List,Join,Clojure,我来自Python世界,在那里很容易进行平均/分组。但我正在用clojure编程,我想从一个大的查询结果中计算每个文章ID的平均值 格式化查询结果后,我得到了类似的结果(这是一个示例,结果要大得多): 我想先有这样的想法: (“123”[233320]“234”[25]) 这就是想法,最终结果将是: ({:文章编号“123”:平均276.5}{:文章编号“234”:平均25}) 所以我需要两个步骤:列出值,然后应用均值函数。第二部分对我来说听起来不错,但我在第一步就被绊倒了:列出值 1) 方法1
(defn list-column [query fields]
(let [values (into {} (map (fn [x] {(x :Article_ID) []}) query))]
(map clojure.walk/keywordize-keys
(map (partial zipmap fields) values))))
推出:
(list-column sample ["Article_ID" "Values"])
所以我有
({:Article_ID "123" :Values []} {:Article_ID "234" :Values []} {:Article_ID "123" :Values []}
2) 方法2:
我也试过了
(defn list-column [query]
(into {} (map (fn [x] {(x :Article_ID) []}) query)))
拥有:
("123" [] "234" [])
我现在只关注列表部分
1) 计算平均值的最佳方法是什么?不关心最终格式(可以更改)
2) 如何将每个价格附加到每个:值字段
我想我必须使用conj来追加。可能会关联ID匹配,但不知道如何将其组合在一起(不知道如何将第一个列表中的article_ID绑定到第二个列表中的值)
谢谢
编辑:
这是最后一个要重用的函数
(defn agg-mean-value [query key value]
(let [init-list (->> (group-by key sample)
(map (fn [[k v]]
[k (mapv value v)]))
(into {}))]
(map (fn [[k vs]]
{key k value (/ (reduce + vs) (count vs))})
init-list)))
随着我知识的增长,我将在未来对其进行改进。Clojure的功能将完成我认为的第一部分
(group-by :Article_ID sample)
=> {"123" [{:Article_ID "123", :Price 233} {:Article_ID "123", :Price 320}], "234" [{:Article_ID "234", :Price 25}]}
您可以这样计算平均值:
(defn mean [vals]
(/ (apply + vals) (count vals)))
我们可以通过以下方式清理该组:
(->> (group-by :Article_ID sample)
(map (fn [[k v]]
[k (mapv :Price v)]))
(into {}))
=> {"123" [233 320], "234" [25]}
最后应用均值函数得出以下结果:
(->> (group-by :Article_ID sample)
(map (fn [[k v]]
[k (mapv :Price v)]))
(into {})
(vals)
(map mean))
=> (553/2 25)
我通常更喜欢使用
reduce
对值进行分组。它的可读性可能会降低,但我可以更好地控制输出。关于这个具体问题,我承认你没有从使用reduce
(与groupby
相反)中获得太多的价值,但我想无论如何我都会发布
(def groups
(reduce
(fn [m {:keys [Article_ID Price]}]
(assoc m Article_ID (conj (get m Article_ID []) Price)))
{}
sample))
这将为您提供键和向量的hashmap:
=> {"123" [233 320], "234" [25]}
从那里,您可以映射到您的组:
(map (fn [[k vs]]
{:Article_ID k :Mean (/ (reduce + vs) (count vs))})
groups)
并产生您想要的结果:
=> ({:Article_ID "123", :Mean 553/2} {:Article_ID "234", :Mean 25})
一般来说,在(可能未排序的)地图上首先使用
是个坏主意。您应该使用(分组依据:Article\u ID sample)
。最后一个示例与(>>(分组依据:Article\u ID-示例)(VAL(map#)(平均值(mapv:价格%))不一样吗
?看起来差不多。有很多方法可以解决这个问题。不过它可能有一些语法问题。非常感谢,效果很好。我正在探索该语言并尝试一些事情。不理解->>是如何工作的,但这里很清楚。也谢谢,我混合了这两种答案,为大型查询创建了一个可重用的通用函数s
=> ({:Article_ID "123", :Mean 553/2} {:Article_ID "234", :Mean 25})