就地圆形 Spark DataFrame

Posted

技术标签:

【中文标题】就地圆形 Spark DataFrame【英文标题】:Round Spark DataFrame in-place 【发布时间】:2018-05-01 05:16:49 【问题描述】:

我将 .csv 文件读取到 Spark DataFrame。对于 DoubleType 列,是否有办法在读取文件时指定该列应四舍五入到小数点后 2 位?我还为 DataFrameReader API 调用提供了一个自定义模式。这是我的架构和 API 调用:

val customSchema = StructType(Array(StructField("id_1", IntegerType, true),
            StructField("id_2", IntegerType, true), 
            StructField("id_3", DoubleType, true)))

#using Spark's CSV reader with custom schema    
#spark == SparkSession()
val parsedSchema = spark.read.format("csv").schema(customSchema).option("header", "true").option("nullvalue", "?").load("C:\\Scala\\SparkAnalytics\\block_1.csv")

文件读入 DataFrame 后,我可以将小数四舍五入:

parsedSchema.withColumn("cmp_fname_c1", round($"cmp_fname_c1", 3))

但这会创建一个新的DataFrame,所以我也想知道它是否可以就地完成而不是创建一个新的DataFrame。

谢谢

【问题讨论】:

Spark Dataframes 中不允许就地更改。它们是不可变的。 您认为从现有 Dataframe 创建新 Dataframe 对您来说是个问题吗? Spark 数据帧是不可变的,任何转换现有数据帧的操作都会创建一个新数据帧。 花点时间了解 spark 而不是提问。 【参考方案1】:

您可以在加载 CSV 文件时为 customSchema 中的 DoubleType 列指定 DecimalType(10, 2)。假设您有一个包含以下内容的 CSV 文件:

id_1,id_2,Id_3
1,10,5.555
2,20,6.0
3,30,7.444

示例代码如下:

import org.apache.spark.sql.types._

val customSchema = StructType(Array(
  StructField("id_1", IntegerType, true),
  StructField("id_2", IntegerType, true), 
  StructField("id_3", DecimalType(10, 2), true)
))

spark.read.format("csv").schema(customSchema).
  option("header", "true").option("nullvalue", "?").
  load("/path/to/csvfile").
  show
// +----+----+----+
// |id_1|id_2|id_3|
// +----+----+----+
// |   1|  10|5.56|
// |   2|  20|6.00|
// |   3|  30|7.44|
// +----+----+----+

【讨论】:

以上是关于就地圆形 Spark DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

找不到就地操作:梯度计算所需的变量之一已被就地操作修改

“就地”是啥意思?

易宝典——玩转O365中的EXO服务 之四十 创建就地电子数据展示搜索

通过递归就地修改

Quicksort与就地合并排序

C++在终端文件中就地覆盖输出的方法