如何修改 Incanter 数据集中的列?

发布于 2024-10-27 20:23:28 字数 108 浏览 2 评论 0原文

我希望能够转换 incanter 数据集中的单个列,并将结果数据集保存到新的 (csv) 文件中。最简单的方法是什么?

本质上,我希望能够将函数映射到数据集中的列,并用此结果替换原始列。

I'd like to be able to transform an individual column in an incanter data set, and save the resulting data set to a new (csv) file. What is the simplest way to do that?

Essentially, I'd like to be able to map a function over a column in the data set, and replace the original column with this result.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

完美的未来在梦里 2024-11-03 20:23:28

您可以定义类似的内容:

(defn map-data [dataset column fn]
  (conj-cols (sel dataset :except-cols column)
             ($map fn column dataset)))

并使用,因为

(def data (get-dataset :cars))
(map-data data :speed #(* % 2))

更改列名称只有一个问题 - 当我有空闲时间时,我会尝试修复它......

You can define something like:

(defn map-data [dataset column fn]
  (conj-cols (sel dataset :except-cols column)
             ($map fn column dataset)))

and use as

(def data (get-dataset :cars))
(map-data data :speed #(* % 2))

there is only one problem with changing of column names - I'll try to fix it, when I'll have free time...

时光暖心i 2024-11-03 20:23:28

这是两个类似的函数,都是列名和顺序保留。

(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))]

下面是一个说明差异的示例:

=> (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]

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')

Here are two similar functions, both column name and order preserving.

(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))]

And here is an example illustrating the difference:

=> (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]

transform-rows is best for simple transformations, where as transform-column is for when the transformation for one row is dependent on other rows (such as when normalizing a column).

Saving and loading CSV can be done with the standard Incanter functions, so a full example looks like:

(use '(incanter core io)))

(def data (col-names (read-dataset 'data.csv') [:a :b])

(save (transform-rows :a #(* % 2) data) 'transformed-data.csv')
凝望流年 2024-11-03 20:23:28

再说一遍:也许您可以使用数据集的内部结构。

user=> (defn update-column
         [dataset column f & args]
         (->> (map #(apply update-in % [column] f args) (:rows dataset))
           vec
           (assoc dataset :rows)))
#'user/update-column
user=> d
[:col-0 :col-1]
[1 2]
[3 4]
[5 6]

user=> (update-column d :col-1 str "d")
[:col-0 :col-1]
[1 "2d"]
[3 "4d"]
[5 "6d"]

再次应该检查一下这是公共 API 的程度。

Again: maybe you can use the internal structure of the dataset.

user=> (defn update-column
         [dataset column f & args]
         (->> (map #(apply update-in % [column] f args) (:rows dataset))
           vec
           (assoc dataset :rows)))
#'user/update-column
user=> d
[:col-0 :col-1]
[1 2]
[3 4]
[5 6]

user=> (update-column d :col-1 str "d")
[:col-0 :col-1]
[1 "2d"]
[3 "4d"]
[5 "6d"]

Again it should be checked in how far this is public API.

或十年 2024-11-03 20:23:28

注意:此解决方案需要 Incanter 1.5.3 或更高版本

对于那些可以使用最新版本的 Incanter...

添加列 & 添加-衍生-列 在 1.5.3 中添加到 Incanter (pull request)

来自文档:

add-column

”将具有给定值的列添加到数据集中。”

(add-column column-name values)

或者

(add-column column-name values data)

或者您可以使用:

add-衍生-列

“此函数将一列添加到数据集中,该数据集是以下函数的函数
现有的列。如果没有提供数据集,$data(由
with-data 宏)将被使用。 f 应该是函数
from-columns,参数按该顺序。”

(add-derived-column column-name from-columns f)

(add-derived-column column-name from-columns f data)

更完整的示例

(use '(incanter core datasets))
  (def cars (get-dataset :cars))

(add-derived-column :dist-over-speed [:dist :speed] (fn [d s] (/ d s)) cars)

(with-data (get-dataset :cars)
  (view (add-derived-column :speed**-1 [:speed] #(/ 1.0 %))))

NOTE: this solution requires Incanter 1.5.3 or greater

For those who can use recent versions of Incanter...

add-column & add-derived-column were added to Incanter in 1.5.3 (pull request)

From the docs:

add-column

"Adds a column, with given values, to a dataset."

(add-column column-name values)

or

(add-column column-name values data)

Or you can use:

add-derived-column

"This function adds a column to a dataset that is a function of
existing columns. If no dataset is provided, $data (bound by the
with-data macro) will be used. f should be a function of the
from-columns, with arguments in that order."

(add-derived-column column-name from-columns f)

or

(add-derived-column column-name from-columns f data)

a more complete example

(use '(incanter core datasets))
  (def cars (get-dataset :cars))

(add-derived-column :dist-over-speed [:dist :speed] (fn [d s] (/ d s)) cars)

(with-data (get-dataset :cars)
  (view (add-derived-column :speed**-1 [:speed] #(/ 1.0 %))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文