使用scala将spark数据帧中的单行拆分为两行
我在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
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列您的输出数据框包含多少列。