【问题标题】:Defining data-specific Clojure functions, possibly with macro?定义特定于数据的 Clojure 函数,可能使用宏?
【发布时间】:2014-09-26 20:22:30
【问题描述】:

我正在处理大量数据,处理的类型取决于正在处理的数据。最终目标是为每一行的每个元素提供一个高效执行的函数。下面是一个使用平均除法的简单示例,但我试图找到一个可以应用任何函数的解决方案。

假设我想读入一个由数字向量组成的向量,并返回第一个数字除以其所在位置的平均数的结果,以及从第二个数字中减去最小数字的结果。

例子:

输入:

(def inputs
[[1.0,1.0]
 [2.0,4.0]
 [3.0,9.0]])

平均:

(def avgs
[2.0,7.0])

最小值:

(def mins
[1.0,1.0])

输出:

(def outputs
[[0.50,0.00]
 [1.00,3.00]
 [1.50,8.00]])

指令:

(def avg-ids [0]) (def subtr-ids [1])

一种天真的方法是查找每个位置的除数:

(defn avg-elem [element position]
  (/ element (nth avgs position)))

(defn subtr-elem [element position]
  (- element (nth mins position)))

(mapv
    #(map-indexed
      (fn [elem idx] (if (is-avg-idx? idx) (avg-elem elem idx) (subtr-elem elem idx)))
    %)
inputs)

我想做的是:

(fn [elem] (/ elem 2.0))
(fn [elem] (- elem 1.0))

并有某种函数将相应的函数应用于每行中的每个元素。

【问题讨论】:

  • 我不清楚您所说的“可以应用任何功能的解决方案”是什么意思。 Clojure 的序列处理原语没有提供什么您需要的东西?你能举一个更好的例子吗?老实说,在我看来,您在不清楚自己的需求是什么的情况下进行了过度设计。
  • 基本上,我正在寻找处理向量(矩阵)的向量,如图所示。当我收到矩阵时,我会收到每列的指令列表。每个指令对应一个函数。应用程序必须具有灵活性,以便将来轻松包含新的指令和功能。现在,我使用类似于幼稚方法的方法,但效率非常低。

标签: macros clojure etl


【解决方案1】:

我不确定您要做什么,但这里有一些方法可以将inputs 矩阵的每一列划分为avgs 向量的相应元素:

(mapv (partial mapv /) inputs (repeat avgs))

(mapv #(mapv / % avgs) inputs)

【讨论】:

  • 我的目标是为每一列定义一个函数。虽然您的解决方案完成了我所布置的确切方案,但它并没有推广到我可能希望在列上执行的其他功能。我会更新说明。
  • @user1559027 泛化到其他函数,将/ 替换为其他函数。
【解决方案2】:

这就是你所追求的吗?

(def row-fns (map (fn [avg] #(/ % avg)) avgs))
(mapv (fn [row] (mapv #(%1 %2) row-fns row)) inputs)

row-fns 替换为任何单参数函数列表。

【讨论】:

  • 采用这种方法会阻止每次处理元素时从 avgs 中查找所需元素吗? row-fns 可以包含不同类型的函数吗?看起来是这样的。
猜你喜欢
  • 2020-05-18
  • 2012-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2021-07-05
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多