Scala 将RDD[字符串]拆分为RDD[元组]
我是Scala和RDD的初学者。我在Spark 2.4上使用Scala。我有一个RDD[String],行如下:Scala 将RDD[字符串]拆分为RDD[元组],scala,apache-spark,bigdata,rdd,Scala,Apache Spark,Bigdata,Rdd,我是Scala和RDD的初学者。我在Spark 2.4上使用Scala。我有一个RDD[String],行如下: (a, b, c, d, ...) 我想在每个coma处拆分此字符串,以获得RDD[(字符串,字符串,字符串,…)] 就元素的数量而言,下面这样的解决方案显然是不可能的 rdd.map(x => (x.split(",")(0), x.split(",")(1), x.split(",")(2))) 有没有办法让它自动化?一切正常 尽管我做出了努力,但到目前为止我的问题还没
(a, b, c, d, ...)
我想在每个coma处拆分此字符串,以获得RDD[(字符串,字符串,字符串,…)]
就元素的数量而言,下面这样的解决方案显然是不可能的
rdd.map(x => (x.split(",")(0), x.split(",")(1), x.split(",")(2)))
有没有办法让它自动化?一切正常
尽管我做出了努力,但到目前为止我的问题还没有得到解决
非常感谢 如果元素的数量是固定的,则可以执行以下操作:
val tuples =
rdd
.map(line => line.replaceAll("[\\(\\)]", "").split(","))
.collect {
case Array(col1, col2, ..., coln) => (col1, col2, ..., coln)
}
// tuples: RDD[(String, String, ..., String)]
一种解决方案是只编写映射函数:
def parse(s: String) = s.split(",") match {
case Array(a,b,c) => (a,b,c)
}
parse("x,x,x") // (x,x,x)
您可以使用shapeless编写更通用的解决方案:
def toTuple[H <: HList](s: String)(implicit ft: FromTraversable[H], t: Tupler[H]) = s.split(",").toHList[H].get.tupled
或先修复,然后键入,然后使用:
def parse3(s: String) = toTuple[String :: String :: String :: HNil](s)
parse3("x,x,x") // (x,x,x)
请注意,最大元组大小限制为22,因此列出所有元组不会太长 顺便说一下,在《火花在行动》一书的第110页,它写道: 没有优雅的方法将数组转换为元组,因此您必须求助于这个丑陋的表达式:
元组的大小是固定的,你知道有多少元素会包含你的字符串吗?嗯,不知道,但我可能会找到一种方法来计算逗号的数量。假设我知道我的元组大小,那么解决方案是什么?我的意思是你必须在编译时知道元组的大小。如果元素的数量可能不同,那么您就不能真正使用元组,您必须使用
Array
。哦,好的,在我的例子中,元素的数量是固定的。如果一行的列数不正确怎么办?映射到RDD[Seq[String]]
不是更简单吗?这个解决方案应该可以工作,但我有200多个元组:/n然后,最好只进行拆分并创建一个列(数组)的DataFrame
,然后使用explode从中创建新列。或者将文件读取为行的数据帧(使用文本),然后使用正则表达式或其他方法将其分解。我认为你应该尝试这种方式,如果你有问题,创造一个新的问题,提供更多的细节。
def parse3(s: String) = toTuple[String :: String :: String :: HNil](s)
parse3("x,x,x") // (x,x,x)
scala> val itPostsRDD = itPostsSplit.map(x => (x(0), x(1), x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10), x(11), x(12))
itPostsRDD: org.apache.spark.rdd.RDD[(String, String, ...