我是clojure的新手,想要正确地做到这一点。我有两个来自两个CSV文件的日期标记数据的数据源。我把它们放在矢量格式的矢量中。我想做一个连接(外连接)的数据组合。
;--- this is how I am loading the data for each file.... works great ---
(def csvfile (slurp "table.csv"))
(def csvdat (clojure.string/split-lines csvfile))
(def final (vec (rest (map (fn [x] (clojure.string/split x #",")) csvdat))))
CSV文件1: date value1 value2 value3
CSV文件2: 日期值A valueB valueC
矢量格式的结果向量: date value1 value2 value3 valueA valueB valueC
我有几个丑陋的想法,我只想做最好的丑陋想法。 :)
选项1:在sequnence中获得一组唯一的时间,并将来自两个向量向量的所有数据映射到一个新的向量向量 选项2:我是否有一种聪明的方法可以从两个向量向量到一个新的向量向量进行映射(比我可以根据自己的经验更高级的映射)
做“连接”的clojure idomatic方法最多的是什么?我应该做地图吗?我喜欢矢量,因为我会在csv加入后进行大量的范围计算,比如将一个窗口(行组)向下移动到连接数据的行中。
答案 0 :(得分:0)
您的数据:
(def csv1 [["01/01/2012" 1 2 3 4]["06/15/2012" 38 24 101]])
(def csv2 [["01/01/2012" 99 98 97 96]["06/15/2012" 28 101 43]])
将CSV的矢量表示向量转换为map:
(defn to-map [v] (into {} (map (fn [[date & data]] [date data]) v)))
合并地图:
(merge-with into (to-map csv1) (to-map csv2))
答案 1 :(得分:-1)
据我了解,您的数据看起来像这样:
(def csv1 [["01/01/2012" 1 2 3 4]["06/15/2012" 38 24 101]])
(def csv2 [["01/01/2012" 99 98 97 96]["06/15/2012" 28 101 43]])
好吧,你可以制作一张地图。
repl-test.core=> (map #(hash-map (keyword (first %1)) (vec (rest %1))) csv1)
({:01/01/2012 [1 2 3 4]} {:06/15/2012 [38 24 101]})
现在,您有另一个csv文件,可能是也可能不是相同的顺序(上面的csv2)。
假设我选择了一行csv1:
(def l1 (first csv1))
["01/01/2012" 1 2 3 4]
并从同一行csv2
连接相同日期的向量(concat (hash-map (keyword (first l1)) (vec (concat (rest l1) [44 43 42]))))
([:01/01/2012 [1 2 3 4 44 43 42]])
我将把这些功能的写作留给你作为练习。
这是你想做的吗?
以下是使用lein new bene-csv之后的一些组件:
(defproject bene-csv "1.0.4-SNAPSHOT"
:description "A csv parsing library"
:dependencies [[org.clojure/clojure "1.4.0"]
[clojure-csv/clojure-csv "1.3.2"]
[util "1.0.2-SNAPSHOT"]]
:aot [bene-csv.core]
:omit-source true)
(ns bene-csv.core
^{:author "Charles M. Norton",
:doc "bene-csv is a small library to parse a .csv file.
Created on March 8, 2012"}
(:require [clojure.string :as cstr])
(:require [util.core :as utl])
(:use clojure-csv.core))
core.clj中的(defn ret-csv-data
"Returns a lazy sequence generated by parse-csv.
Uses utl/open-file which will return a nil, if
there is an exception in opening fnam.
parse-csv called on non-nil file, and that
data is returned."
[fnam]
(let [ csv-file (utl/open-file fnam)
inter-csv-data (if-not (nil? csv-file)
(parse-csv csv-file)
nil)
csv-data (vec
(filter
#(and pos? (count %) (not (nil? (rest %))))
inter-csv-data))]
(pop csv-data)))