我是新手,我需要帮助解决这个问题。
我有一个像这样的csv文件:
ANI,2974483123 29744423747 293744450542,Twitter,@ani
我需要拆分第二列" 2974483123 29744423747 293744450542"并创建如下三行:
ANI,2974483123,Twitter,@ani
ANI,29744423747,Twitter,@ani
ANI,293744450542,Twitter,@ani
有人能帮助我吗?请!
答案 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')]