pyspark 数据框立方体方法返回重复的空值

Posted

技术标签:

【中文标题】pyspark 数据框立方体方法返回重复的空值【英文标题】:pyspark dataframe cube method returning duplicate null values 【发布时间】:2018-03-20 00:33:39 【问题描述】:

我有以下数据(可以复制粘贴复制):

from pyspark.sql import Row
l = [Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=None), Row(value=None), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=None), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=None)]
l_df = spark.createDataFrame(l)

我们看一下l_df的schema:

l_df.printSchema()

root
|-- value: boolean (nullable = true)

现在我想使用cube() 来计算value 列中每个不同值的频率:

l_df.cube("value").count().show()

但我看到了两种类型的 null 值!

+-----+-----+
|value|count|
+-----+-----+
| true|   67|
| null|  100|
| null|   33|
+-----+-----+

验证我实际上没有两种类型的null

l_df.select("value").distinct().collect()

null确实只有一种类型:

[Row(value=None), Row(value=True)]

只是为了仔细检查:

l_df.select("value").distinct().count()

它返回2

我还注意到len(l)100 并且第一个null 等于这个数字。为什么会这样?

系统信息:Spark 2.1.0、Python 2.7.8、[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2

【问题讨论】:

没有我的环境可用于测试 ATM,但为什么不直接做 l_df.groupBy('value').count().show() 是的,那行得通。但是我仍然想弄清楚为什么cube() 不起作用... 【参考方案1】:

这不是两种类型的空值,而是不同级别聚合的结果。正如What is the difference between cube, rollup and groupBy operators? 中所述,您的cube 应用程序相当于:

SELECT NULL AS value, COUNT(*) FROM df
UNION ALL
SELECT value, COUNT(*) FROM df GROUP BY value

第一个查询生成元组(null, 100)(记录总数),其中NULL 只是一个占位符,第二个查询生成元组(true, 67)(null, 33),其中NULL 是@ 的级别之一987654329@专栏。

使用grouping(或grouping_id)很容易检查:

from pyspark.sql.functions import grouping, count

l_df.cube("value").agg(count("*"), grouping("value")).show()
# +-----+--------+---------------+
# |value|count(1)|grouping(value)|
# +-----+--------+---------------+
# | true|      67|              0|
# | null|     100|              1|
# | null|      33|              0|
# +-----+--------+---------------+

【讨论】:

【参考方案2】:

df.groupBy('value').count().show() 会像@pault 所说的那样做。

对于多维数据集,添加“过滤器”方法对我有用

df.cube("value").count().filter(  col('count')<df.count()  ).show()

但是添加了一个额外的过程。查看我使用 cube() 的工作的屏幕截图。

【讨论】:

以上是关于pyspark 数据框立方体方法返回重复的空值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PySpark 中用该列的第一个非空值填充该列的空值

Pyspark 计数非空值之间的空值

从 Pyspark 中的数据框中计算空值和非空值

逐行计算pyspark数据帧中的空值数

为啥针对 S3 的 pyspark sql 查询返回空值

Pyspark:如何处理 python 用户定义函数中的空值