Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将RDD[字符串]拆分为RDD[元组]_Scala_Apache Spark_Bigdata_Rdd - Fatal编程技术网

Scala 将RDD[字符串]拆分为RDD[元组]

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))) 有没有办法让它自动化?一切正常 尽管我做出了努力,但到目前为止我的问题还没

我是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)))
有没有办法让它自动化?一切正常

尽管我做出了努力,但到目前为止我的问题还没有得到解决


非常感谢

如果元素的数量是固定的,则可以执行以下操作:

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, ...