【问题标题】:What would be the functional way of getting the mean of each vector in Clojure?在 Clojure 中获取每个向量的平均值的功能方法是什么?
【发布时间】:2018-04-01 02:20:20
【问题描述】:

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

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

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

【问题讨论】:

    标签: clojure functional-programming


    【解决方案1】:

    我会进一步分解它并使用map 而不是for。我个人喜欢有很多更小的函数:

    (defn mean [row]
      (/ (apply + row) (count row)))
    
    (defn mean-rows [rows]
      (map mean rows))
    

    但这与@Alan 的回答大致相同。

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

    【讨论】:

    • 这种情况下reduceapply有区别吗?
    • @VascoFerreira 不。他们做同样的事情。如果您查看 + 的重载,您会发现它接受 var-args 重载。 var-arg 重载基本上是对+ 的减少。
    • 恕我直言,“让它更实用”的关键点:开发/提取最有用的功能(在这种情况下为mean)总是一个好主意,如果你真的需要它,给(map f seq) 一个名字(比如mean-rows)——但在那时它只是一件小事。
    • @cfrick 我也认为“最小的功能组件”是 FP 原则,我找不到任何好的参考资料表明它实际上与 FP 相关。我认为总的来说这是一种很好的做法,而且有时我几乎走得太远了。我想添加一个参考链接和一些简介,但我找不到任何好的来源。
    【解决方案2】:

    这是一个简单的答案:

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

    如果你还没有看过,可以从这里开始:https://www.braveclojure.com/

    我建议购买这本书的印刷版,因为它比在线版要多。

    【讨论】:

      猜你喜欢
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      • 2017-09-23
      相关资源
      最近更新 更多