我有一个clojure函数,它使用flambo v0.60函数api对样本数据集进行一些分析。我注意到当我使用(get rdd 2)
而不是获取rdd集合中的第二个元素时,它获取rdd集合的第一个元素的第二个字符。我的假设是clojure将rdd集合的每一行视为一个完整的字符串而不是一个向量,以便我能够获得集合中的第二个元素。我正在考虑使用map-values函数将映射的值转换为我可以得到第二个元素的向量,我试过这个:
(defn split-on-tab-transformation [xctx input]
(assoc xctx :rdd (-> (:rdd xctx)
(spark/map (spark/fn [row] (s/split row #"\t")))
(spark/map-values vec))))
不幸的是我收到了一个错误:
java.lang.IllegalArgumentException: No matching method found: mapValues for class org.apache.spark.api.java.JavaRDD...
这是代码返回rdd中的第一个集合:
(假设我删除了上述函数中的(spark/map-values vec)
(defn get-distinct-column-val
"input = {:col val}"
[ xctx input ]
(let [rdds (-> (:rdd xctx)
(f/map (f/fn [row] row))
f/first)]
(clojure.pprint/pprint rdds)))
输出:
[2.00000 770127 200939.000000 \t6094\tBENTONVILLE, AR DPS\t22.500000\t5.000000\t2.500000\t5.000000\t0.000000\t0.000000\t0.000000\t0.000000\t0.000000\t1\tStore Tab\t0.000000\t4.50\t3.83\t5.00\t0.000000\t0.000000\t0.000000\t0.000000\t19.150000]
如果我尝试获取第二个元素770127
(defn get-distinct-column-val
"input = {:col val}"
[ xctx input ]
(let [rdds (-> (:rdd xctx)
(f/map (f/fn [row] row))
f/first)]
(clojure.pprint/pprint (get rdds 1)))
我明白了:
[\.]
Flambo documentation for map-values
我是clojure的新手,我很感激任何帮助。感谢
答案 0 :(得分:1)
首先,map-values
(或Spark API中的mapValues
)仅在PairRDD上有效转换(例如此类[:foo [1 2 3]]
。具有此类值的RDD可以被解释作为一些某种地图,其中第一个元素是一个键,第二个元素是一个值。
如果您有这样的RDD mapValues
转换值而不更改密钥。在这种情况下,你应该使用第二个地图,虽然它似乎已经过时,因为clojure.string/split
已经返回了一个向量。
使用map-values
的简单示例:
(let [pairs [(ft/tuple :foo 1) (ft/tuple :bar 2)]
rdd (f/parallelize-pairs sc pairs) ;; Note parallelize-pairs -> PairRDD
result (-> rdd
(f/map-values inc) ;; Map values
(f/collect))]
(assert (= result [(ft/tuple :foo 2) (ft/tuple :bar 3)])))
根据您的描述,您似乎正在使用输入RDD而不是从split-on-tab-transformation
返回的RDD。如果我不得不猜测您是否尝试使用原始xctx
,而不是split-on-tab-transformation
返回的原始maps
。由于Clojure assoc
是不可变的,get-distinct-column-val
不会更改传递的参数,而RDD[String]
会收到RDD[Array[String]]
而不会(spit "data.txt"
(str "Mazda RX4\t21\t6\t160\n"
"Mazda RX4 Wag\t21\t6\t160\n"
"Datsun 710\t22.8\t4\t108\n"))
根据命名约定,我假设您希望为数组中的单个位置获取不同的值。为清楚起见,我删除了代码中未使用的部分。首先让我们创建虚拟数据:
(defn split-on-tab-transformation [xctx]
(assoc xctx :rdd (-> (:rdd xctx)
(f/map #(clojure.string/split % #"\t")))))
(defn get-distinct-column-val
[xctx col]
(-> (:rdd xctx)
(f/map #(get % col))
(f/distinct)))
添加功能的重写版本
(assert
(= #{"Mazda RX4 Wag" "Datsun 710" "Mazda RX4"}
(-> {:sc sc :rdd (f/text-file sc "data.txt")}
(split-on-tab-transformation)
(get-distinct-column-val 0)
(f/collect)
(set))))
和结果
var foods:JSON?{
didSet{
self.setupFood()
}
}
func setupFood(){
return value = {
"total_count": 1,
"foods": [{
"food_name": "fish",
"article_id": 122
}],
"table": {"table_id": 60,
"table_name": "far left"}
}
}