使用scala将单行拆分为spark数据帧中的两行

时间:2017-08-03 15:32:52

标签: scala apache-spark spark-dataframe

我有火花数据框中的数据,如下所示

nm    date        id       amount
1233  2017-01-23  9253194  2323
1234  2017-01-24  9253196  4455
1235  2017-01-25  9253195  5677

我的输出应该是

1233
2017-01-23  9253194  2323
1234
2017-01-24  9253196  4455
1235
2017-01-25  9253195  5677

请有人帮我解决这个问题。 感谢。

3 个答案:

答案 0 :(得分:0)

好吧,看起来你不想要一个DataFrame作为输出,否则你的每一行都有类似的结构。看看这是否有帮助:

//我尝试快速重新创建数据框。仅供参考,您可以跳过

val myList = List((1233,"2017-01-23",9253194,2323),(1234,"2017-01-24",9253196,4455),(1235,"2017-01-25",9253195,5677))
val myDF = myList.toDF(Seq("nm","date","id","amount"): _*)
scala> myDF.printSchema
root
 |-- nm: integer (nullable = false)
 |-- date: string (nullable = true)
 |-- id: integer (nullable = false)
 |-- amount: integer (nullable = false)

//以及如何以您指定的方式打印。

myDF.foreach(row => println(row.get(0)+" \n"+row.get(1)+" "+row.get(2)+" "+row.get(3)))

如果你想在DataFrame结构中使用它,你必须在每一行中保留3个字段,然后只用一个值填充一个字段,接下来将填充所有3个值。它太乱了,而且通常不太现实。

答案 1 :(得分:0)

我不确定您是否要记录/打印以该格式控制数据帧或继续处理此类数据帧。

如果你想要一个具有这种结构的数据帧,下面的代码会产生它:

import org.apache.spark.sql.{Row, SparkSession}
object Test extends App {
  val sparkSession = SparkSession.builder().appName("test").master("local[*]").getOrCreate()
  import sparkSession.implicits._

  val columns = Seq("nm","date","id","amount")
  val input = List(
    (1233, "2017-01-23", 9253194, 2323),
    (1234, "2017-01-24", 9253196, 4455),
    (1235, "2017-01-25", 9253195, 5677)
  )

  sparkSession.createDataset(input).toDF(columns: _*)
    .repartition(1)
    .flatMap {
      case Row(nm: Int, date: String, id: Int, amount: Int) =>
        List[(String, Int, Int)](
          (nm.toString, null.asInstanceOf[Int], null.asInstanceOf[Int]),
          (date, id, amount)
        )
      }
    .foreach(row => Console.println(row))
}

但有一些问题:

  • 第一列和第二列中有不同的类型,因此必须转换第一列

  • Spark可以在任何行重新分配数据集,因此最终输出可能如下所示:

(1233,null,null) (1235,null,null) (1234,null,null) (2017-01-23,9253194,2323) (2017-01-25,9253195,5677) (2017-01-24,9253196,4455)

  • 因为写入任何输出会产生或多或少的随机结果

  • 现在你的行没有一致数量的非空列,如果你忘了它,你会在某个时候引用一个包含null的列/字段

  • 您无法对行进行排序

  • 再次对其进行分组(包含4列的行)根本不可能(除非您不关心结果是否正确)

总之,如果要以该格式打印行,则应定义一个从给定行生成String的函数。

如果您想处理具有此类结构的数据帧,请不要这样做。

答案 2 :(得分:0)

可以使用spark sql轻松完成:

list()