计算 Spark 数据帧中非空值的数量



我有一个包含一些列的数据框,在进行分析之前,我想了解数据框的完整性。因此,我想过滤数据框并计算每列的非空值数量,可能会返回数据帧。

基本上,我试图达到与这个问题中表达的相同的结果,但使用 Scala 而不是 Python。

假设您有:

val row = Row("x", "y", "z")
val df = sc.parallelize(Seq(row(0, 4, 3), row(None, 3, 4), row(None, None, 5))).toDF()

如何汇总每列的非空值数,并返回具有相同列数且仅包含答案的单行的数据帧?

一个简单的选项是使用 .describe() 函数获取数据框的摘要,其中计数行包含非空值的计数:

df.describe().filter($"summary" === "count").show
+-------+---+---+---+
|summary|  x|  y|  z|
+-------+---+---+---+
|  count|  1|  2|  3|
+-------+---+---+---+

虽然我喜欢 Psidoms 的答案,但通常我对空值的比例更感兴趣,因为只有非空值的数量并不能说明太多......

您可以执行以下操作:

import org.apache.spark.sql.functions.{sum,when, count}
df.agg(
   (sum(when($"x".isNotNull,0).otherwise(1))/count("*")).as("x : fraction null"),
   (sum(when($"y".isNotNull,0).otherwise(1))/count("*")).as("y : fraction null"),
   (sum(when($"z".isNotNull,0).otherwise(1))/count("*")).as("z : fraction null")
 ).show()

编辑:sum(when($"x".isNotNull,0).otherwise(1))也可以替换为仅计算非空值的count($"x")。由于我发现这并不明显,我倾向于使用更清晰的sum表示法

以下是我在 Scala 2.11、Spark 2.3.1 中的做法:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._
df.agg(
    count("x").divide(count(lit(1)))
        .as("x: percent non-null")
    // ...copy paste that for columns y and z
).head()

count(*)对非空行进行计数,count(1)对每一行运行。

如果您想计算总体中的百分比,请找到我们基于计数的方程的补码:

lit(1).minus(
    count("x").divide(count(lit(1)))
    )
    .as("x: percent null")

同样值得一提的是,您可以将 nullness 转换为整数,然后将其求和
但它的性能可能较差:

// cast null-ness to an integer
sum(col("x").isNull.cast(IntegerType))
    .divide(count(lit(1)))
    .as("x: percent null")

这是最简单的查询:

d.filter($"x" !== null ).count
df.select(df.columns map count: _*)

df.select(df.columns map count: _*).toDF(df.columns: _*)

Spark 2.3+
(对于字符串和数字类型列)

df.summary("count").show()
+-------+---+---+---+
|summary|  x|  y|  z|
+-------+---+---+---+
|  count|  1|  2|  3|
+-------+---+---+---+

相关内容

  • 没有找到相关文章

最新更新