我希望能够转换incanter数据集中的单个列,并将结果数据集保存到新的(csv)文件中.最简单的方法是什么?
基本上,我希望能够在数据集中的列上映射函数,并用此结果替换原始列.
你可以定义类似的东西:
(defn map-data [dataset column fn]
(conj-cols (sel dataset :except-cols column)
($map fn column dataset)))
Run Code Online (Sandbox Code Playgroud)
并用作
(def data (get-dataset :cars))
(map-data data :speed #(* % 2))
Run Code Online (Sandbox Code Playgroud)
更改列名只有一个问题 - 我会尝试修复它,当我有空闲时间时......
这里有两个类似的功能,包括列名和保留顺序.
(defn transform-column [col-name f data]
(let [new-col-names (sort-by #(= % col-name) (col-names data))
new-dataset (conj-cols
(sel data :except-cols col-name)
(f ($ col-name data)))]
($ (col-names data) (col-names new-dataset new-col-names) )))
(defn transform-rows [col-name f data]
(let [new-col-names (sort-by #(= % col-name) (col-names data))
new-dataset (conj-cols
(sel data :except-cols col-name)
($map f col-name data))]
Run Code Online (Sandbox Code Playgroud)
这是一个说明差异的例子:
=> (def test-data (to-dataset [{:a 1 :b 2} {:a 3 :b 4}]))
=> (transform-column :a (fn [x] (map #(* % 2) x)) test-data)
[:a :b]
[2 2]
[6 4]
=> (transform-rows :a #(* % 2) test-data)
[:a :b]
[2 2]
[6 4]
Run Code Online (Sandbox Code Playgroud)
transform-rows最适合简单转换,其中transform-column一行的转换依赖于其他行(例如,对列进行规范化时).
保存和加载CSV可以使用标准的Incanter功能完成,因此完整的示例如下所示:
(use '(incanter core io)))
(def data (col-names (read-dataset 'data.csv') [:a :b])
(save (transform-rows :a #(* % 2) data) 'transformed-data.csv')
Run Code Online (Sandbox Code Playgroud)