在clojure中实现flambo mapValues函数
我有一个clojure函数,它使用flambo v0.60函数api对样本数据集进行一些分析。我注意到,当我使用在clojure中实现flambo mapValues函数,clojure,apache-spark,rdd,flambo,Clojure,Apache Spark,Rdd,Flambo,我有一个clojure函数,它使用flambo v0.60函数api对样本数据集进行一些分析。我注意到,当我使用(getrdd2)而不是获取rdd集合中的第二个元素时,它获取rdd集合中第一个元素的第二个字符。我的假设是clojure将rdd集合中的每一行视为一个完整的字符串,而不是一个向量,这样我就可以获得集合中的第二个元素。我正在考虑使用map values函数将映射值转换为向量,我可以得到第二个元素,我尝试了以下方法: (defn split-on-tab-transformation [
(getrdd2)
而不是获取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:找不到匹配的方法:org.apache.spark.api.java.JavaRDD类的mapValues…
这是返回rdd中第一个集合的代码:
(假设我在上述函数中删除了(火花/贴图值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)))
我得到:
[\.]
我是clojure新手,非常感谢您的帮助。首先,感谢
map values
(或Spark API中的map values
)仅在PairRDD上是有效的转换(例如类似以下内容[:foo[1 2 3]]
.rdd的值可以解释为某种映射,其中第一个元素是键,第二个元素是值
如果您有像这样的RDDmapValues
在不更改键的情况下转换值。在这种情况下,您应该使用第二个映射,尽管它似乎已过时,因为clojure.string/split
已返回向量
使用映射值的一个简单示例
:
(让[pairs[(ft/tuple:foo 1)(ft/tuple:bar 2)]
rdd(f/parallelize pairs sc pairs);;注意parallelize pairs->PairRDD
结果(->rdd
(f/地图价值公司);地图价值
(f/收集)]
(断言(=结果[(英尺/元组:foo 2)(英尺/元组:bar 3)])
从您的描述来看,您使用的是一个输入RDD,而不是从选项卡转换时的拆分返回的RDD。如果我不得不猜测您试图使用的是原始的xctx
,而不是从选项卡转换时的拆分返回的RDD。因为Clojure映射
是不可变的assoc
不可更改更改已传递的参数并get distinct column val
receivesRDD[String]
notRDD[Array[String]
基于命名约定,我假设您希望为数组中的单个位置获取不同的值。为了清晰起见,我删除了代码中未使用的部分。首先,让我们创建虚拟数据:
(spit“data.txt”
(str“马自达RX4\t21\t6\t160\n”
“马自达RX4 Wag\t21\t6\t160\n”
“Datsun 710\t22.8\t4\t108\n”))
添加函数的重写版本
(选项卡转换时的defn拆分[xctx]
(assoc xctx:rdd(->)(:rdd xctx)
(f/map#(clojure.string/split%#“\t“#”)))
(defn获取不同的列val
[xctx col]
(->)(:rdd xctx)
(f/map#(获取%col))
(f(b)
和结果
(断言)
(=#{“马自达RX4 Wag”“Datsun 710”“马自达RX4”}
(->{:sc:rdd(f/text文件sc“data.txt”)}
(选项卡转换时拆分)
(获取不同的列值0)
(f/收取)
(集)
@noisesmith你能帮我解决这个问题吗challenge@cbbetz你能帮我解决这个flambo和clojure问题吗谢谢。我是否可以在不使用assoc
的情况下用rdd上的最新的转换来更新:rdd
,或者assoc
正在运行使用转换中的值更新:rdd
键。实际上,您对这个问题的假设是正确的。我非常感谢您的帮助..我只想澄清一下assoc
clojure函数。clojure数据结构是不可变的,因此实际上没有更新这样的事情。您总是会得到一个新的数据一个结构。你可以把xctx
变成一个并使用swap!
但我怀疑这是个好主意。像上面这样捕获一个输出是一个更干净的解决方案,可以确保引用的透明性。顺便说一句,如果你喜欢答案,我不介意向上投票:-)示例中还有一个问题,split on tab transformation
是否会更改:rdd
键在xctx
中的值,这样当get distinct column val
在xctx中使用:rdd
键时,它实际上会使用split on tab transformation
中的新值,而不是它以前的值?ThanksecxActly.在选项卡转换时拆分
返回assoc
的结果,这是一个新映射,:rdd
等于(:rdd xctx)…)
并将其传递到get distinct column val
。使用可变状态会给代码增加一个全新的复杂性。因此,在我看来,基本问题是它是否真的值得。一般来说,我会说它不值得。我不确定您首先为什么需要xctx
。我没有使用它的经验flambo
(今天第一次)和Clojure(除非你算上一些玩具项目),但说到Spark,简单地传递RDD是很自然的。因为RDD和转换只是一个配方,它是一种轻量级的方法,使程序的推理变得更容易。