【问题标题】:Count the number of non-null values in a Spark DataFrame计算 Spark DataFrame 中非空值的数量
【发布时间】:2017-06-05 13:34:37
【问题描述】:

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

基本上,我试图达到与this question 中表达的相同的结果,但使用 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()

你如何总结每列的非空数并返回一个具有相同列数且只有一行的数据框的答案?

【问题讨论】:

  • 非常感谢,如果您能分享一些 sn-ps 以更好地理解您提出的逻辑,我将不胜感激:我可以编写一个 UDF 来执行此操作,但我不知道该怎么做编写一段代码,为每一列执行 UDF

标签: scala apache-spark-sql


【解决方案1】:

这是最简单的查询:

d.filter($"x" !== null ).count

【讨论】:

    【解决方案2】:

    虽然我喜欢 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 表示法

    【讨论】:

    • @user299791 忘记提及导入
    【解决方案3】:

    这是我在 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) 在每一行上运行。

    如果您想计算人口中的百分比null,请找到我们基于计数的等式的补集:

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

    值得了解的是,您可以将空值转换为整数,然后对其求和
    但它可能性能较差:

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

    【讨论】:

    • 你也可以用count("*")代替count(lit(1)),我觉得这样更易读
    【解决方案4】:

    一个直接的选择是使用.describe() 函数来获取数据框的摘要,其中计数行包括非空值的计数:

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

    【讨论】:

    • 这仅适用于数字列,不适用于字符串...对吗?
    • 这适用于使用 Spark 2.2.1 的字符串列:使用模式加载,以便我们得到一个只填充空值的字符串列:val xx = spark.read.schema(StructType(Seq(StructField("a", LongType, true), StructField("b", LongType, true), StructField("c", StringType, true), StructField("d", StringType, true)))).json("/tmp/toy.jline") 然后描述。
    猜你喜欢
    • 1970-01-01
    • 2019-01-04
    • 2017-04-14
    • 2019-06-18
    • 1970-01-01
    • 2018-06-27
    • 2017-11-20
    • 2015-07-10
    • 1970-01-01
    相关资源
    最近更新 更多