【问题标题】:How to split pipe-separated column into multiple rows?如何将管道分隔的列拆分为多行?
【发布时间】:2017-05-14 13:41:01
【问题描述】:

我有一个包含以下内容的数据框:

movieId / movieName / genre
1         example1    action|thriller|romance
2         example2    fantastic|action

我想获得第二个数据帧(来自第一个),其中包含以下内容:

movieId / movieName / genre
1         example1    action
1         example1    thriller
1         example1    romance
2         example2    fantastic
2         example2    action

我该怎么做?

【问题讨论】:

    标签: apache-spark apache-spark-sql


    【解决方案1】:

    我会使用split 标准函数。

    scala> movies.show(truncate = false)
    +-------+---------+-----------------------+
    |movieId|movieName|genre                  |
    +-------+---------+-----------------------+
    |1      |example1 |action|thriller|romance|
    |2      |example2 |fantastic|action       |
    +-------+---------+-----------------------+
    
    scala> movies.withColumn("genre", explode(split($"genre", "[|]"))).show
    +-------+---------+---------+
    |movieId|movieName|    genre|
    +-------+---------+---------+
    |      1| example1|   action|
    |      1| example1| thriller|
    |      1| example1|  romance|
    |      2| example2|fantastic|
    |      2| example2|   action|
    +-------+---------+---------+
    
    // You can use \\| for split instead
    scala> movies.withColumn("genre", explode(split($"genre", "\\|"))).show
    +-------+---------+---------+
    |movieId|movieName|    genre|
    +-------+---------+---------+
    |      1| example1|   action|
    |      1| example1| thriller|
    |      1| example1|  romance|
    |      2| example2|fantastic|
    |      2| example2|   action|
    +-------+---------+---------+
    

    附言您可以使用Dataset.flatMap 来实现相同的结果,我敢肯定 Scala 开发人员会更喜欢这一点。

    【讨论】:

    • '@Jacek..你提到了其他答案,但只有一个答案是你的..
    • @stack0114106 谢谢。在此期间,它们似乎已被删除。消除答案中的噪音。
    • @JacekLaskowski 如果我们有两列,我们如何拆分 |分隔符。例如,除了流派之外,如果我们还有一个具有多个名称的“演员”列。
    • @Ahmad 关心提出一个单独的问题,以便我们有更多的空间和可见性来讨论您的用例?谢谢。
    【解决方案2】:

    使用 RDD

    val df = Seq((1,"example1","action|thriller|romance"),(2,"example2","fantastic|action")).toDF("Id","name","genre")
    df.rdd.flatMap( x=>{ val p = x.getAs[String]("genre"); for { a <- p.split("[|]") } yield (x(0),x(1),a)} ).foreach(println)
    

    结果:

    (1,example1,action)
    (2,example2,fantastic)
    (1,example1,thriller)
    (2,example2,action)
    (1,example1,romance)
    

    转换回DF

    val rdd1 = df.rdd.flatMap( x=>{ val p = x.getAs[String]("genre"); for { a <- p.split("[|]") } yield Row(x(0),x(1),a)} )
    spark.createDataFrame(rdd1,df.schema.copy(Array(StructField("Id",IntegerType),StructField("name",StringType))).add(StructField("genre2",StringType))).show(false)
    

    【讨论】:

      猜你喜欢
      • 2020-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多