Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.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将spark数据帧中的单行拆分为两行_Scala_Apache Spark_Spark Dataframe - Fatal编程技术网

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

使用scala将spark数据帧中的单行拆分为两行,scala,apache-spark,spark-dataframe,Scala,Apache Spark,Spark Dataframe,我在spark数据框中有如下数据 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

我在spark数据框中有如下数据

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
谁能帮我一下吗。
谢谢。

看来您不希望数据帧作为输出,否则每一行的结构都会相似。看看这是否有帮助:

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

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个值。这很混乱,而且通常不现实。好吧,似乎您不希望数据帧作为输出,否则您的每一行都有类似的结构。看看这是否有帮助:

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

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个值。需要这种格式是很混乱的,而且通常是不现实的。

我不确定您是想记录/打印以控制这种格式的数据帧,还是继续处理这种数据帧

如果需要具有这种结构的数据帧,则以下代码将生成它:

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,空,空)
(1235,空,空)
(1234,空,空)
(2017-01-23,9253194,2323)
(2017-01-25,9253195,5677)
(2017-01-24,9253196,4455)

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

  • 现在,您的行的非空列数不一致,如果您忘记了这一点,您将在某个时候引用包含null的列/字段

  • 不能对行进行排序

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

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


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

我不确定您是要记录/打印以该格式控制数据帧,还是继续处理这种数据帧

如果需要具有这种结构的数据帧,则以下代码将生成它:

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,空,空)
(1235,空,空)
(1234,空,空)
(2017-01-23,9253194,2323)
(2017-01-25,9253195,5677)
(2017-01-24,9253196,4455)

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

  • 现在,您的行的非空列数不一致,如果您忘记了这一点,您将在某个时候引用包含null的列/字段

  • 不能对行进行排序

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

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


如果您想使用这种结构处理数据帧,请不要这样做。

使用spark sql可以轻松完成:

sqlContext.sql("select cast(nm as string) from df 
           union all select cast(date as string) + ' ' 
                          + cast(id as string) + ' ' 
                          + cast(amount as string) from df")

可以使用spark sql轻松完成:

sqlContext.sql("select cast(nm as string) from df 
           union all select cast(date as string) + ' ' 
                          + cast(id as string) + ' ' 
                          + cast(amount as string) from df")

那么您的新数据框只有一列?否。不同行中的第一列和不同行中的其余3列您的输出数据框包含多少列。那么您的新数据框只有一列?否。不同行中的第一列和不同行中的其余3列您的输出数据框包含多少列。