从 Incanter 数据集中获取一系列列(作为向量或其他)的最佳方法是什么?
我想到了:
(to-vect (trans (to-matrix my-dataset)))
但理想情况下,我想要一个惰性序列。有没有更好的办法?
使用$
宏。
=> (def data (to-dataset [{:a 1 :b 2} {:a 3 :b 4}]))
=> ($ :a data) ;; :a column
=> ($ 0 :all data) ;; first row
=> (type ($ :a data))
clojure.lang.LazySeq
查看to-vect
它的源代码用于map
构建结果,这已经提供了某种程度的惰性。不幸的是,看起来整个数据集都是先转换toArray
的,可能只是放弃了懒惰的所有好处map
。
如果您想要更多,您可能必须深入研究有效保存数据集的矩阵版本的Java 对象的血腥细节,并编写您自己的 to-vect 版本。
您可以使用数据集的内部结构。
user=> (use 'incanter.core)
nil
user=> (def d (to-dataset [{:a 1 :b 2} {:a 3 :b 4}]))
#'user/d
user=> (:column-names d)
[:a :b]
user=> (:rows d)
[{:a 1, :b 2} {:a 3, :b 4}]
user=> (defn columns-of
[dataset]
(for [column (:column-names dataset)]
(map #(get % column) (:rows dataset))))
#'user/columns-of
user=> (columns-of d)
((1 3) (2 4))
虽然我不确定内部结构在多大程度上是公共 API。你可能应该和咒术师核实一下。