当前位置: 首页 > 知识库问答 >
问题:

Spark和Scala中数据帧的转换模式

岳谦
2023-03-14

我想使用Spark和Scala强制转换dataframe的模式以更改某些列的类型。

具体地说,我正在尝试使用AS[U]函数,其描述为:“返回一个新的数据集,其中每个记录都映射到指定的类型。用于映射列的方法取决于U的类型。”

原则上,这正是我想要的,但我不能使它起作用。

下面是一个取自https://github.com/apache/spark/blob/master/sql/core/src/test/scala/org/apache/spark/sql/datasetsuite.scala的简单示例



    // definition of data
    val data = Seq(("a", 1), ("b", 2)).toDF("a", "b")

正如所预期的,数据的架构是:


    root
     |-- a: string (nullable = true)
     |-- b: integer (nullable = false)
    

我想把“B”栏翻倍。所以我尝试以下方法:



    import session.implicits._;

    println(" --------------------------- Casting using (String Double)")

    val data_TupleCast=data.as[(String, Double)]
    data_TupleCast.show()
    data_TupleCast.printSchema()

    println(" --------------------------- Casting using ClassData_Double")

    case class ClassData_Double(a: String, b: Double)

    val data_ClassCast= data.as[ClassData_Double]
    data_ClassCast.show()
    data_ClassCast.printSchema()

根据我对As[u]的定义的理解,新的DataFrames应该具有以下模式


    root
     |-- a: string (nullable = true)
     |-- b: double (nullable = false)

但输出是


     --------------------------- Casting using (String Double)
    +---+---+
    |  a|  b|
    +---+---+
    |  a|  1|
    |  b|  2|
    +---+---+

    root
     |-- a: string (nullable = true)
     |-- b: integer (nullable = false)

     --------------------------- Casting using ClassData_Double
    +---+---+
    |  a|  b|
    +---+---+
    |  a|  1|
    |  b|  2|
    +---+---+

    root
     |-- a: string (nullable = true)
     |-- b: integer (nullable = false)

这表明列“B”没有转换为double。

我做错了什么?

顺便说一句:我知道前一篇文章“如何在Spark SQL的DataFrame中更改列类型?”(请参见如何在Spark SQL的DataFrame中更改列类型?)。我知道我可以一次一个地更改列的类型,但我正在寻找一个更通用的解决方案,在一次拍摄中更改整个数据的模式(并且我正在尝试在这个过程中理解Spark)。

共有1个答案

谭修然
2023-03-14

好吧,由于函数是链接的,而Spark执行惰性计算,所以它实际上会在一次拍摄中更改整个数据的模式,即使您将其写成更改一列,如下所示:

import spark.implicits._

df.withColumn("x", 'x.cast(DoubleType)).withColumn("y", 'y.cast(StringType))...

作为另一种选择,我认为您可以使用map一次性完成角色转换,例如:

df.map{t => (t._1, t._2.asInstanceOf[Double], t._3.asInstanceOf[], ...)}
 类似资料:
  • 我有一个如下的CSV文件。 我想把这个转化成下面。 基本上,我想在输出数据帧中创建一个名为idx的新列,该列将填充与键=idx,value=“n”后面的行相同的值“n”。

  • RDD是以数组[数组[字符串]的格式创建的,具有以下值: 我想用模式创建一个数据帧: 接下来的步骤: 给出以下错误:

  • 我得到以下错误:org.apache.spark.sql.analysisException:不允许在另一个聚合函数的参数中使用聚合函数。请在子查询中使用内部聚合函数。;; 我尝试了多种解决方案来解决这个问题,但似乎没有任何效果。所有的想法都得到了赞赏。谢了!

  • 我正在考虑将dataset1分解为每个“T”类型的多个记录,然后与DataSet2连接。但是你能给我一个更好的方法,如果数据集变大了,它不会影响性能吗?

  • 我正在尝试访问配置单元表,并从表/数据帧中提取和转换某些列,然后将这些新列放入新的数据帧中。我试着用这种方式- 它使用SBT构建时没有任何错误。但当我尝试运行它时,我收到以下错误- 我想了解是什么导致了这个错误,如果有任何其他的方法来完成我正在尝试做的事情。

  • 我正在尝试将熊猫DF转换为Spark one。测向头: 代码: 我得到了一个错误: