在scala中我看到reduceByKey((x: Int , y Int) => x + y)
,但我想将一个值迭代为字符串并进行一些比较。我们是否可以reduceByKey
使用reduceByKey(x: String , y: String)
?
代码:
val sparkConf = new SparkConf().setMaster("local").setAppName("Spark AVRO Read")
val sc = new SparkContext(sparkConf)
val inPath= "/home/053764/episodes.avro"
val sqlContext = new SQLContext(sc)
val df = sqlContext.read.avro(inPath)
val rows: RDD[Row] = df.rdd
val doc = df.select("doctor").rdd.map(r => r(0) val docsss = rows.map(r => (r(2), r(1)))
val reduce = docsss.reduceByKey((first, second) => {
val firstDate = LocalDateTime.parse(first)
val secondDate = LocalDateTime.parse(second)
if (firstDate.isBefore(secondDate)) first else second
})
请告诉我如何使用按键减少
将值重复为字符串答案 0 :(得分:1)
PairRDDFunctions.reduceByKey
适用于RDD[(K, V)]
形式的任何RDD。 reduceByKey
将采用类型K
(可以使用等式检查进行正确比较),并为任何类型(V, V) => V
调用函数V
。
这是一个(Int,String)元组的简短示例,其中减少了两个字符串:
val sc = new SparkContext(conf)
val rdd = sc.parallelize(Seq((1, "01/01/2014"), (1, "02/01/2014")))
rdd.reduceByKey((first, second) => {
val firstDate = LocalDateTime.parse(first)
val secondDate = LocalDateTime.parse(second)
if (firstDate.isBefore(secondDate)) first else second
})
正如@TheArchetypalPaul正确指出的那样,由于日期是年/零填充月/零填充日的常量格式,您可以利用lexicographical order并比较两个String
值而不是将它们解析为DateTime
个对象。这基本上减少了代码:
val sc = new SparkContext(conf)
val rdd = sc.parallelize(Seq((1, "01/01/2014"), (1, "02/01/2014")))
rdd.reduceByKey((first, second) => if (first > second) first else second)
请注意,这确实限制了您使用的特定格式。如果情况发生变化,您最好使用为日期创建LocalDateTime
对象的第一个版本。
答案 1 :(得分:0)
当我尝试将Docsss的类型声明为字符串时,我没有声明任何类型:
val docsss : String = rows.map(r => (r(2),r(1)))
它的说法
type mismatch; found : org.apache.spark.rdd.RDD[(Any, Any)]
required: String val rows: RDD[Row] = df.rdd