Apache Spark stddev_pop()和avg()聚合函数的不同类型

xn1cxnb4  于 2023-05-18  发布在  Apache
关注(0)|答案(1)|浏览(287)

我有一个包含decimal(38,8)类型的列的数据框,我对它执行一些操作以计算该列的标准差和平均值。
下面是数据框架的模式和内容

root
 |-- key: string (nullable = false)
 |-- count: decimal(38,4) (nullable = false)
计数
2_AN8068571086_EPA_EUR_PID1742804_ik两万
2_AN8068571086_EPA_EUR_PID1742804_ik一万
2_AN8068571086_EPA_EUR_PID1742804_ik两万
2_AN8068571086_EPA_EUR_PID1742804_ik4.0000
2_AN8068571086_EPA_EUR_PID1742804_ik两万
2_AN8068571086_EPA_EUR_PID1742804_ik两万
2_AN8068571086_EPA_EUR_PID1742804_ik一万

当我进行以下操作时

df.groupBy(col("key")).agg(stddev_pop("count").as("std dev"), avg("count").as("average"))

生成的模式为

root
 |-- key: string (nullable = false)
 |-- std dev: double (nullable = true)
 |-- average: decimal(38,8) (nullable = true)

这导致用于STDDEV和平均列的不同格式(不同的小数数目
| 键|标准差|平均|
| --------------|--------------|--------------|
| 2_AN8068571086_EPA_EUR_PID1742804_ik| 3.499271061118826| 4.57142900|
我的问题:为什么stddev_pop()和avg()的输出类型不同?我应该强制转换两列中的一列(例如std dev为decimal(38,4)类型)以具有相同的格式,还是有其他方法来格式化双精度值?
下面是一个重现此行为的简化示例:

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

val schema = StructType(
     Seq(
     StructField("key", StringType, nullable = false),
     StructField("count", DecimalType(38,4), nullable = false)
     )
     )

val data = Seq(
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(2.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(10.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(2.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(4.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(2.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(2.0)),
     Row("2_AN8068571086_EPA_EUR_PID1742804_ik", BigDecimal(10.0))
     )
val df = spark.createDataFrame(spark.sparkContext.parallelize(data), schema)
 
df.printSchema()
df.show(false)

val df1 = df.groupBy(col("key")).agg(stddev_pop("count").as("std dev"), avg("count").as("average"))

df1.printSchema()
df1.show(false)
h5qlskok

h5qlskok1#

我的猜测是decimal的平均值可以表示为decimal,这就是为什么decimal用于avg,而stddev根据定义是真实的,这就是为什么使用double。我不会将double转换为decimal,因为这有点奇怪,相反,将avg转换为double似乎更合理,但这真的取决于你列的语义

相关问题