【问题标题】:replacing spark dataset column values randomly from a set从集合中随机替换 spark 数据集列值
【发布时间】:2017-11-21 06:23:24
【问题描述】:

有一个数据集 imputedcsv,我想将 Gender 列中的空值随机替换为 Male 或 Female..

imputedcsv.groupBy("Gender").count.show()

+------+-----+
|Gender|count|
+------+-----+
|  null|   24|
|Female|  240|
|  Male|  242|
+------+-----+

一个用单个值填充空值,但是如何从一组值中随机填充列的空值说{Male,Female}

imputedcsv.na.fill("Male", Seq("Gender")).groupBy("Gender").count.show()

+------+-----+
|Gender|count|
+------+-----+
|Female|  240|
|  Male|  266|
+------+-----+

我需要用MaleFemale 随机填充它,而不是只用一个值Male 替换空值。

类似于使用sample(c('Male','Female'))

对于单个值,我们有 How to replace null values with a specific value in Dataframe using spark in Java?

感谢任何帮助。

【问题讨论】:

    标签: apache-spark apache-spark-sql spark-dataframe


    【解决方案1】:

    如果您认为 Gender 是 FemaleMale 的概率相等,您可以这样做:

    df.withColumn( "gender", 
        coalesce($"gender", 
                     when(round(rand).cast("int") === lit(0) , lit("Male") )
                     .otherwise(lit("Female"))
                 )).show
    

    coalesce 使其仅适用于 null 值。 round(rand).cast("int") 每次都会生成01,然后MaleFemale 将由when - otherwise 构造决定。

    【讨论】:

    • 似乎 df.na.fill 只取一个值...所以对于不同的运行,我们会随机获得男性或女性,,,,但是一旦获得一个值..该值用于填满所有的 NAs..
    • val r = new scala.util.Random val genderMap = Map(1 -> "Female", 0 -> "Male") val newdf1=imputedcsv.na.fill(genderMap.getOrElse(Math .round(r.nextFloat) , "Female" ) ) newdf1.groupBy("Gender").count.show() 结果:Run1:男性 242 女性 264 Run2:男性:266 女性:240
    • 它有效..谢谢..任何指针..关于合并如何使其仅适用于空值的解释..
    • coalesce 是一个预定义的函数,它采用任意数量的列。假设如果一个查询被定义为coalesce(a, "Hello"),那么它将返回Hello,只要a 是NULL,否则它将返回列a 的原始值。请接受答案,以便将问题标记为已解决。谢谢。
    • 谢谢。接受了答案。祝你有美好的一天!
    【解决方案2】:

    您可以使用when & otherwisewithColumn 来实现它,如下所示:

    scala> df.groupBy("Gender").count.show
    
    +------+-----+
    |Gender|count|
    +------+-----+
    |  null|    2|
    |female|    4|
    |  male|    4|
    +------+-----+
    
    scala> df.withColumn("gender", when(($"gender".isNull), "male").otherwise($"gender")).groupBy("gender").count.show
    +------+-----+
    |gender|count|
    +------+-----+
    |female|    4|
    |  male|    6|
    +------+-----+
    

    我错过了randomly,你可以像下面这样实现它:

    scala> val gender_set = Set("male","female")
    gender_set: scala.collection.immutable.Set[String] = Set(male, female)
    
    scala> import scala.util.Random
    import scala.util.Random
    
    scala>  val rnd=new Random
    rnd: scala.util.Random = scala.util.Random@668b5a55
    
    scala> df.withColumn("gender", when(($"gender".isNull), gender_set.toVector(rnd.nextInt(gender_set.size))).otherwise($"gender")).groupBy("gender").count.show
    +------+-----+
    |gender|count|
    +------+-----+
    |female|    4|
    |  male|    6|
    +------+-----+
    
    
    scala> df.withColumn("gender", when(($"gender".isNull), gender_set.toVector(rnd.nextInt(gender_set.size))).otherwise($"gender")).groupBy("gender").count.show
    +------+-----+
    |gender|count|
    +------+-----+
    |female|    6|
    |  male|    4|
    +------+-----+
    

    谢谢。

    【讨论】:

    • 如果你想在你的 sn-p 中使用单个值..“男性”,上面的内容很好。我正在探索从“男性”或“女性”中分配一个随机值。
    【解决方案3】:

    我需要将 @Learner 的代码放入 UDF 中才能工作,否则会出错。

    df.groupBy($"Gender").count.show()
    +------+-----+
    |Gender|count|
    +------+-----+
    |  null|    3|
    |Female|    3|
    |  Male|    2|
    +------+-----+
    val gender_set = Set("Male","Female")
    
    val randGenderUDF = udf(() => 
       gender_set.toVector(rnd.nextInt(gender_set.size))
    )
    
    df.withColumn("Gender", when($"Gender".isNull, randGenderUDF()).otherwise($"Gender")).groupBy($"Gender").count.show()
    +------+-----+
    |Gender|count|
    +------+-----+
    |Female|    5|
    |  Male|    3|
    +------+-----+    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2018-09-24
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      相关资源
      最近更新 更多