apache-spark - Spark如何计算字符串列的均值和标准差
问题描述
我有以下数据(仅显示一个片段)
DEST_COUNTRY_NAME ORIGIN_COUNTRY_NAME count
United States Romania 15
United States Croatia 1
United States Ireland 344
Egypt United States 15
我用inferSchema
选项设置为true
然后describe
是列来阅读它。它似乎工作正常。
scala> val data = spark.read.option("header", "true").option("inferSchema","true").csv("./data/flight-data/csv/2015-summary.csv")
scala> data.describe().show()
+-------+-----------------+-------------------+------------------+
|summary|DEST_COUNTRY_NAME|ORIGIN_COUNTRY_NAME| count|
+-------+-----------------+-------------------+------------------+
| count| 256| 256| 256|
| mean| null| null| 1770.765625|
| stddev| null| null|23126.516918551915|
| min| Algeria| Angola| 1|
| max| Zambia| Vietnam| 370002|
+-------+-----------------+-------------------+------------------+
如果我不指定inferSchema
,则所有列都被视为字符串。
scala> val dataNoSchema = spark.read.option("header", "true").csv("./data/flight-data/csv/2015-summary.csv")
dataNoSchema: org.apache.spark.sql.DataFrame = [DEST_COUNTRY_NAME: string, ORIGIN_COUNTRY_NAME: string ... 1 more field]
scala> dataNoSchema.printSchema
root
|-- DEST_COUNTRY_NAME: string (nullable = true)
|-- ORIGIN_COUNTRY_NAME: string (nullable = true)
|-- count: string (nullable = true)
问题1)为什么最后一列Spark
给出mean
和stddev
值count
scala> dataNoSchema.describe().show();
+-------+-----------------+-------------------+------------------+
|summary|DEST_COUNTRY_NAME|ORIGIN_COUNTRY_NAME| count|
+-------+-----------------+-------------------+------------------+
| count| 256| 256| 256|
| mean| null| null| 1770.765625|
| stddev| null| null|23126.516918551915|
| min| Algeria| Angola| 1|
| max| Zambia| Vietnam| 986|
+-------+-----------------+-------------------+------------------+
问题 2)如果Spark
现在解释count
为numeric
列,那么为什么max
值是 986 而不是 37002(就像在数据 DataFrame 中一样)
解决方案
Spark SQL 渴望符合 SQL 标准,因此使用相同的评估规则,并且如果需要,透明地强制类型以满足表达式(例如,参见我 对PySpark DataFrames 的回答 - 使用不同类型的列之间的比较进行过滤)。
这意味着max
and mean
/ stddev
case 根本不等效:
maximum 对字符串有意义(使用字典顺序)并且不需要强制
Seq.empty[String].toDF("count").agg(max("count")).explain
== Physical Plan == SortAggregate(key=[], functions=[max(count#69)]) +- Exchange SinglePartition +- SortAggregate(key=[], functions=[partial_max(count#69)]) +- LocalTableScan <empty>, [count#69]
平均值或标准偏差不是,并且参数被转换为 double
Seq.empty[String].toDF("count").agg(mean("count")).explain
== Physical Plan == *(2) HashAggregate(keys=[], functions=[avg(cast(count#81 as double))]) +- Exchange SinglePartition +- *(1) HashAggregate(keys=[], functions=[partial_avg(cast(count#81 as double))]) +- LocalTableScan <empty>, [count#81].
推荐阅读
- php - 获取多对多关系中的计数以进行记录编辑
- c# - 如何使用 jQuery 在弹出窗口中显示 JSON 解析数据
- xpath - 如何在 Firefox 开发者版中找到 XPath?
- sql - 从数字sql中的字符串替换多个值
- javascript - 如何在 JavaScript 中设置系统属性
- node.js - 安装节点模块时找不到模块“genfun”
- ios - UIView 的继承,用于添加新逻辑或扩展 UIViewController
- c++ - 由于 alpha 值,将一张图像混合到另一张图像会产生不正确的图像
- actionscript-3 - AS3扩展圆形时如何创建多种颜色?
- javascript - 停止变量干扰/变量范围