获得Clojure中每个向量的平均值的函数方法是什么?

获得Clojure中每个向量的平均值的函数方法是什么?,clojure,functional-programming,Clojure,Functional Programming,我是函数式编程和Clojure编程语言的初学者,几乎所有的事情我都在求助于recur。我有一个csv格式的数据集,作为地图导入。我已经提取了我需要用作向量的信息。每一列都是一个向量,我想计算每一列的平均值。我编写了以下函数: (defn mean "Calculate the mean for each column" ([columns] (mean columns [])) ([columns means] (if (empty? columns)

我是函数式编程和Clojure编程语言的初学者,几乎所有的事情我都在求助于
recur
。我有一个csv格式的数据集,作为地图导入。我已经提取了我需要用作向量的信息。每一列都是一个向量,我想计算每一列的平均值。我编写了以下函数:

(defn mean
  "Calculate the mean for each column"
  ([columns]
   (mean columns []))
  ([columns
    means]
   (if (empty? columns)
     means
     (recur (rest columns)
            (conj means (float (/ (reduce + (first columns)) (count (first columns)))))))))

;; Calcule the mean for the following vectors
(mean [[1 2 3] [1 2 3] [1 2 3]])
; => [2.0 2.0 2.0]

这是解决这个问题的实用方法吗?

这里有一个简单的答案:

(defn mean
  "Calculate the mean of each column"
  [cols]
  (vec    ; this is optional if you don't want it
    (for [col cols]
      (/                      ; ratio of num/denom
        (reduce + col)        ; calculates the numerator
        (count col)))))       ; the number of items

(mean [[1 2 3] [1 2 3] [1 2 3]]) => [2 2 2]
如果您还没有看到,可以从这里开始:


我建议买这本书的印刷版,因为它比在线版有更多的内容。

我会进一步细分,使用
map
,而不是
。我个人喜欢有许多更小的功能:

(defn mean [row]
  (/ (apply + row) (count row)))

(defn mean-rows [rows]
  (map mean rows))
但这和艾伦的答案是一样的


你这样做的方式已经被认为是“功能性的”。应该说,虽然使用
recur
很好,但通常使用
reduce
,或者至少使用
map
,您可以更轻松地实现所需。这些选项消除了显式递归的需要,通常会产生更简单、更容易理解的代码。

在这种情况下,
reduce
apply
之间有什么区别吗?@VascoFerreira没有。它们做同样的事情。如果查看
+
的重载,您将看到它接受var args重载。var arg重载基本上是对
+
的一种简化。“使其更具功能性”的关键点是:开发/提取最有用的函数(
mean
,在本例中)总是一个好主意,如果您确实需要它,请给
(map f seq)
一个名称(如
平均行
)-但在这一点上,这只是一个微不足道的问题。@cfrick我也认为“最小的功能组件”是一个FP原则,我找不到任何好的参考文献说明它实际上与FP相关。我认为这是一个很好的做法,虽然一般来说,和一个我几乎采取了太远的时候。我想添加一个参考链接和一个小广告,但我找不到任何好的来源。