从集合中随机替换 spark 数据集列值
Posted
技术标签:
【中文标题】从集合中随机替换 spark 数据集列值【英文标题】:replacing spark dataset column values randomly from a set 【发布时间】: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|
+------+-----+
我需要用Male
或Female
随机填充它,而不是只用一个值Male
替换空值。
类似于使用sample(c('Male','Female'))
对于单个值,我们有 How to replace null values with a specific value in Dataframe using spark in Java?
感谢任何帮助。
【问题讨论】:
【参考方案1】:如果您认为 Gender 是 Female
或 Male
的概率相等,您可以这样做:
df.withColumn( "gender",
coalesce($"gender",
when(round(rand).cast("int") === lit(0) , lit("Male") )
.otherwise(lit("Female"))
)).show
coalesce
使其仅适用于 null
值。
round(rand).cast("int")
每次都会生成0
或1
,然后Male
或Female
将由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 & otherwise
和withColumn
来实现它,如下所示:
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|
+------+-----+
【讨论】:
以上是关于从集合中随机替换 spark 数据集列值的主要内容,如果未能解决你的问题,请参考以下文章