Clojure是否具有与Mathematica中的BinCounts类似的功能?

时间:2013-11-23 00:19:40

标签: clojure

在BinCounts函数中输入一个向量(Mathematica中的列表),最小,最大和宽度大小。该函数计算在最小到最大间隔内指定宽度的连续区间中的元素数。

示例输入将是 ([1 3 2 1 4 5 6 2] 0 10 1)其中0对应最小值,10表示最大值,1表示箱宽。

然后输出该函数 [0 2 2 1 1 1 1 0 0 0]

这引起了另一个问题,因为在Mathematica中,无穷大是最小值或最大值的有效输入(忽略符号)。在指定间隔时,Clojure会处理这样的输入吗?

没有给出间隔的另一个例子 ([1 3 2 1 4 5 6 2] 2)其中2是箱宽

输出[2 3 2 1]

2 个答案:

答案 0 :(得分:4)

Clojure没有内置此功能,但编写起来相当简单:

user> (defn bin-counts [data min max width] 
        (for [bucket (range min max)] 
          (count (filter #(<= bucket % (+ width bucket)) data))))
#'user/bin-counts

user> (bin-counts [1 3 2 1 4 5 6 2] 0 10 1)
(2 4 3 2 2 2 1 0 0 0)

user> (bin-counts [1 3 2 1 4 5 6 2] 0 10 0)
(0 2 2 1 1 1 1 0 0 0)

更完整的版本将为min max等提供默认值。

答案 1 :(得分:1)

以下解决方案仅通过data进行一次传递。

(defn bin-counts [data min max width]
  (let [buckets (->> data
                   (filter #(and (<= min %) (< % max))) ; in range
                   (map #(quot (- % min) width))) ; convert to bucket number
        bucket-count (quot (- max min) width)]
    (reduce
     #(assoc %1 %2 (inc (%1 %2)))
     (vec (repeat bucket-count 0))
     buckets)))
  • buckets是有效存储桶编号的延迟序列。
  • reduce增加每个此类的计数(最初为零) 发生。

至于无穷大,Clojure从Java继承Double/NEGATIVE_INFINITYDouble/POSITIVE_INFINITY。这些行为与<之类的行为一样。例如,您可以将它们用作range函数的终点。

user=> (take 10 (range 0 Double/NEGATIVE_INFINITY -1))
(0 -1 -2 -3 -4 -5 -6 -7 -8 -9)

事实上,range使用Double/POSITIVE_INFINITY作为默认终点。