如何为具有 True、False 和 Null 值的布尔字段创建分层样本?

How to create a stratified sample for a boolean field with True, False and Null values?

我有一个带有布尔字段的 DataFrame。

df = spark.createDataFrame([
  [True],   
  [False],   
  [None],
  [True],   
  [False],
  [None]
]).toDF("match")

我想创建一个具有相等 True、False 和 Null 值的分层样本 (PySpark)。

我怎样才能在我的样本中也得到 Null 值(None: 0.3 不被接受)

sampled = df.sampleBy("match", fractions={True: 0.3, False: 0.3})

基于source code of sampleBy method, the parameter fractions is a Map[T, Double], and for a MapType column with Spark, null keys are not allowed (see doc)

def sampleBy[T](col: String, fractions: Map[T, Double], seed: Long): DataFrame = {
  sampleBy(Column(col), fractions, seed)
}

一个可能的解决方案是添加一个标志以将 FalseTrueNULL 转换为 012然后根据这个标志做sampleBy,例如:

from pyspark.sql.functions import expr

df_sample = df.withColumn('flag', expr("coalesce(int(match), 2)")) \
    .sampleBy("flag", {0:0.3, 1:0.3, 2:0.3}) \
    .drop("flag")