我有一个带有一些列的数据框,在进行分析之前,我想了解这样的数据帧是多么完整,所以我想过滤数据帧并为每列计算非空值的数量,可能返回数据帧回来了。
基本上,我试图获得与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()
如何汇总每列的非空数并返回具有相同列数的数据帧,只返回一行的答案?
虽然我喜欢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
只计算非空值。当我发现这不明显时,我倾向于使用更清晰的.describe()
表示法
一个直接的选择是使用df.describe().filter($"summary" === "count").show
+-------+---+---+---+
|summary| x| y| z|
+-------+---+---+---+
| count| 1| 2| 3|
+-------+---+---+---+
函数来获取数据框的摘要,其中count行包含非空值的计数:
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()
这是我在Scala 2.11,Spark 2.3.1中的表现:
count(*)
count(1)
计算非空行,lit(1).minus(
count("x").divide(count(lit(1)))
)
.as("x: percent null")
在每一行上运行。
如果您想要计算总体中的百分比null,请找到基于计数的等式的补码:
// cast null-ness to an integer
sum(col("x").isNull.cast(IntegerType))
.divide(count(lit(1)))
.as("x: percent null")
同样值得知道的是,您可以将null转换为整数,然后对其求和。 但它可能性能较差:
qazxswpoi