Какой идиоматический способ получить последовательность столбцов из набора данных заклинателя?
Каков наилучший способ получить последовательность столбцов (в виде векторов или чего-либо еще) из набора данных Incanter?
Я думал о:
(to-vect (trans (to-matrix my-dataset)))
Но в идеале я бы хотел ленивую последовательность. Есть ли способ лучше?
3 ответа
Использовать $
макро.
=> (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. Вы, наверное, должны проверить это с парнями-заклинателями.