拆分字段并从一行创建多行Spark-Scala

时间:2016-03-01 20:41:30

标签: scala apache-spark

我是新手,我需要帮助解决这个问题。

我有一个像这样的csv文件:

ANI,2974483123 29744423747 293744450542,Twitter,@ani

我需要拆分第二列" 2974483123 29744423747 293744450542"并创建如下三行:

ANI,2974483123,Twitter,@ani

ANI,29744423747,Twitter,@ani

ANI,293744450542,Twitter,@ani

有人能帮助我吗?请!

3 个答案:

答案 0 :(得分:8)

flatMap正在寻找:

val input: RDD[String] = sc.parallelize(Seq("ANI,2974483123 29744423747 293744450542,Twitter,@ani"))
val csv: RDD[Array[String]] = input.map(_.split(','))

val result = csv.flatMap { case Array(s1, s2, s3, s4) => s2.split(" ").map(part => (s1, part, s3, s4)) }

答案 1 :(得分:1)

这是一个稍微不同的解决方案,它利用了Spark可用的内置SQL UDF。理想情况下,应使用这些来代替自定义函数,以利用查询优化器(https://blog.cloudera.com/blog/2017/02/working-with-udfs-in-apache-spark/)提供的性能改进。

import org.apache.spark.sql.functions.{split, explode}

val filename = "/path/to/file.csv"
val columns = Seq("col1","col2","col3","col4")

val df = spark.read.csv(filename).toDF(columns: _*)

// import "split" instead of writing your own split UDF
df.withColumn("col2", split($"col2", " ")).
  // import "explode instead of map then flatMap
  select($"col1", explode($"col2"), $"col3", $"col4").take(10)

答案 2 :(得分:0)

非常类似于Tzach的答案,但是在python2中并且要小心多空格分隔符。

import re

rdd = sc.textFile("datasets/test.csv").map(lambda x: x.split(","))

print(rdd.take(1))
print(rdd.map(lambda (a, b, c, d): [(a, number, c, d) for number in re.split(" +", b)])
         .flatMap(lambda x: x)
         .take(10))

#[[u'ANI', u'2974481249 2974444747 2974440542', u'Twitter', u'maximotussie']]
#[(u'ANI', u'2974481249', u'Twitter', u'maximotussie'), 
# (u'ANI', u'2974444747', u'Twitter', u'maximotussie'), 
# (u'ANI', u'2974440542', u'Twitter', u'maximotussie')]